1use 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
97pub 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}