Skip to main content

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