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")]
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
99pub 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}