gsk4/
render_node.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use glib::translate::*;
4
5use crate::{ffi, prelude::*, ParseLocation, RenderNode, RenderNodeType};
6
7impl RenderNode {
8    #[inline]
9    pub fn is<T: IsRenderNode>(&self) -> bool {
10        T::NODE_TYPE == self.node_type()
11    }
12
13    #[inline]
14    pub fn type_(&self) -> glib::Type {
15        unsafe {
16            let ptr = self.as_ptr();
17            from_glib((*(*(ptr as *mut glib::gobject_ffi::GTypeInstance)).g_class).g_type)
18        }
19    }
20
21    #[doc(alias = "gsk_render_node_deserialize")]
22    pub fn deserialize(bytes: &glib::Bytes) -> Option<Self> {
23        assert_initialized_main_thread!();
24        unsafe {
25            from_glib_full(ffi::gsk_render_node_deserialize(
26                bytes.to_glib_none().0,
27                None,
28                std::ptr::null_mut(),
29            ))
30        }
31    }
32
33    #[doc(alias = "gsk_render_node_deserialize")]
34    pub fn deserialize_with_error_func<P: FnMut(&ParseLocation, &ParseLocation, &glib::Error)>(
35        bytes: &glib::Bytes,
36        error_func: P,
37    ) -> Option<Self> {
38        assert_initialized_main_thread!();
39        let mut error_func_data: P = error_func;
40        unsafe extern "C" fn error_func_func<
41            P: FnMut(&ParseLocation, &ParseLocation, &glib::Error),
42        >(
43            start: *const ffi::GskParseLocation,
44            end: *const ffi::GskParseLocation,
45            error: *const glib::ffi::GError,
46            user_data: glib::ffi::gpointer,
47        ) {
48            let start = from_glib_borrow(start);
49            let end = from_glib_borrow(end);
50            let error = from_glib_borrow(error);
51            let callback = user_data as *mut P;
52            (*callback)(&start, &end, &error);
53        }
54        let error_func = Some(error_func_func::<P> as _);
55        let super_callback0: &mut P = &mut error_func_data;
56        unsafe {
57            from_glib_full(ffi::gsk_render_node_deserialize(
58                bytes.to_glib_none().0,
59                error_func,
60                super_callback0 as *mut _ as *mut _,
61            ))
62        }
63    }
64
65    #[inline]
66    pub fn downcast<T: IsRenderNode>(self) -> Result<T, Self> {
67        unsafe {
68            if self.is::<T>() {
69                Ok(from_glib_full(self.into_glib_ptr()))
70            } else {
71                Err(self)
72            }
73        }
74    }
75
76    #[inline]
77    pub fn downcast_ref<T: IsRenderNode>(&self) -> Option<&T> {
78        unsafe {
79            if self.is::<T>() {
80                Some(&*(self as *const RenderNode as *const T))
81            } else {
82                None
83            }
84        }
85    }
86}
87
88impl std::fmt::Debug for RenderNode {
89    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
90        f.debug_struct("RenderNode")
91            .field("bounds", &self.bounds())
92            .field("node_type", &self.node_type())
93            .finish()
94    }
95}
96
97// rustdoc-stripper-ignore-next
98/// A common trait implemented by the various [`RenderNode`](crate::RenderNode)
99/// types.
100///
101/// # Safety
102///
103/// The user is not supposed to implement this trait.
104pub unsafe trait IsRenderNode:
105    StaticType
106    + FromGlibPtrFull<*mut ffi::GskRenderNode>
107    + std::convert::AsRef<crate::RenderNode>
108    + 'static
109{
110    const NODE_TYPE: RenderNodeType;
111    fn upcast(self) -> RenderNode;
112    fn upcast_ref(&self) -> &RenderNode;
113}
114
115#[doc(hidden)]
116impl AsRef<RenderNode> for RenderNode {
117    #[inline]
118    fn as_ref(&self) -> &Self {
119        self
120    }
121}
122
123macro_rules! define_render_node {
124    ($rust_type:ident, $ffi_type:path, $node_type:path) => {
125        impl std::convert::AsRef<crate::RenderNode> for $rust_type {
126            #[inline]
127            fn as_ref(&self) -> &crate::RenderNode {
128                self
129            }
130        }
131
132        impl std::ops::Deref for $rust_type {
133            type Target = crate::RenderNode;
134
135            #[inline]
136            fn deref(&self) -> &Self::Target {
137                unsafe { &*(self as *const $rust_type as *const crate::RenderNode) }
138            }
139        }
140
141        unsafe impl crate::render_node::IsRenderNode for $rust_type {
142            const NODE_TYPE: RenderNodeType = $node_type;
143
144            #[inline]
145            fn upcast(self) -> crate::RenderNode {
146                unsafe {
147                    glib::translate::from_glib_full(
148                        glib::translate::IntoGlibPtr::<*mut $ffi_type>::into_glib_ptr(self)
149                            as *mut crate::ffi::GskRenderNode,
150                    )
151                }
152            }
153
154            #[inline]
155            fn upcast_ref(&self) -> &crate::RenderNode {
156                self
157            }
158        }
159
160        #[doc(hidden)]
161        impl glib::translate::FromGlibPtrFull<*mut crate::ffi::GskRenderNode> for $rust_type {
162            #[inline]
163            unsafe fn from_glib_full(ptr: *mut crate::ffi::GskRenderNode) -> Self {
164                glib::translate::from_glib_full(ptr as *mut $ffi_type)
165            }
166        }
167
168        #[cfg(feature = "v4_6")]
169        #[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
170        impl glib::value::ValueType for $rust_type {
171            type Type = Self;
172        }
173
174        #[cfg(feature = "v4_6")]
175        #[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
176        unsafe impl<'a> glib::value::FromValue<'a> for $rust_type {
177            type Checker = glib::value::GenericValueTypeOrNoneChecker<Self>;
178
179            #[inline]
180            unsafe fn from_value(value: &'a glib::Value) -> Self {
181                skip_assert_initialized!();
182                glib::translate::from_glib_full(crate::ffi::gsk_value_dup_render_node(
183                    glib::translate::ToGlibPtr::to_glib_none(value).0,
184                ))
185            }
186        }
187
188        #[cfg(feature = "v4_6")]
189        #[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
190        impl glib::value::ToValue for $rust_type {
191            #[inline]
192            fn to_value(&self) -> glib::Value {
193                let mut value = glib::Value::for_value_type::<Self>();
194                unsafe {
195                    crate::ffi::gsk_value_set_render_node(
196                        glib::translate::ToGlibPtrMut::to_glib_none_mut(&mut value).0,
197                        self.as_ptr() as *mut _,
198                    )
199                }
200                value
201            }
202
203            #[inline]
204            fn value_type(&self) -> glib::Type {
205                use glib::prelude::StaticType;
206                Self::static_type()
207            }
208        }
209
210        #[cfg(feature = "v4_6")]
211        #[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
212        impl glib::value::ToValueOptional for $rust_type {
213            #[inline]
214            fn to_value_optional(s: Option<&Self>) -> glib::Value {
215                skip_assert_initialized!();
216                let mut value = glib::Value::for_value_type::<Self>();
217                unsafe {
218                    crate::ffi::gsk_value_set_render_node(
219                        glib::translate::ToGlibPtrMut::to_glib_none_mut(&mut value).0,
220                        s.map(|s| s.as_ptr()).unwrap_or(std::ptr::null_mut()) as *mut _,
221                    )
222                }
223                value
224            }
225        }
226    };
227}