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