1use glib::{Object, Type, Value, translate::*, value::FromValue};
4
5use crate::{Expression, ffi, prelude::*};
6
7#[doc(hidden)]
8impl AsRef<Expression> for Expression {
9 #[inline]
10 fn as_ref(&self) -> &Expression {
11 self
12 }
13}
14
15pub unsafe trait IsExpression:
23 StaticType + FromGlibPtrFull<*mut ffi::GtkExpression> + 'static
24{
25}
26
27impl Expression {
28 #[inline]
29 pub fn upcast(self) -> Self {
30 self
31 }
32
33 #[inline]
34 pub fn upcast_ref(&self) -> &Self {
35 self
36 }
37
38 #[inline]
39 pub fn is<E: IsExpression>(&self) -> bool {
40 self.type_().is_a(E::static_type())
41 }
42
43 #[inline]
44 pub fn downcast<E: IsExpression>(self) -> Result<E, Expression> {
45 unsafe {
46 if self.is::<E>() {
47 Ok(from_glib_full(self.into_glib_ptr()))
48 } else {
49 Err(self)
50 }
51 }
52 }
53
54 #[inline]
55 pub fn downcast_ref<E: IsExpression>(&self) -> Option<&E> {
56 unsafe {
57 if self.is::<E>() {
58 Some(&*(self as *const Expression as *const E))
59 } else {
60 None
61 }
62 }
63 }
64
65 #[inline]
66 pub fn type_(&self) -> Type {
67 unsafe {
68 let ptr = self.as_ptr();
69 from_glib((*(*(ptr as *mut glib::gobject_ffi::GTypeInstance)).g_class).g_type)
70 }
71 }
72
73 #[doc(alias = "gtk_expression_evaluate")]
74 pub fn evaluate(&self, this: Option<&impl IsA<Object>>) -> Option<Value> {
75 assert_initialized_main_thread!();
76 unsafe {
77 let mut value = Value::uninitialized();
78 let ret = ffi::gtk_expression_evaluate(
79 self.to_glib_none().0,
80 this.map(|t| t.as_ref()).to_glib_none().0,
81 value.to_glib_none_mut().0,
82 );
83 if from_glib(ret) { Some(value) } else { None }
84 }
85 }
86
87 #[doc(alias = "gtk_expression_evaluate")]
91 pub fn evaluate_as<V: for<'b> FromValue<'b> + 'static, T: IsA<Object>>(
92 &self,
93 this: Option<&T>,
94 ) -> Option<V> {
95 self.evaluate(this).map(|v| {
96 v.get_owned::<V>()
97 .expect("Failed to evaluate to this value type")
98 })
99 }
100
101 pub fn chain_property<T: IsA<glib::Object>>(
106 &self,
107 property_name: &str,
108 ) -> crate::PropertyExpression {
109 crate::PropertyExpression::new(T::static_type(), Some(self), property_name)
110 }
111
112 pub fn chain_closure<R>(&self, closure: glib::RustClosure) -> crate::ClosureExpression
141 where
142 R: glib::value::ValueType,
143 {
144 crate::ClosureExpression::new::<R>([self], closure)
145 }
146
147 pub fn chain_closure_with_callback<F, R>(&self, f: F) -> crate::ClosureExpression
152 where
153 F: Fn(&[glib::Value]) -> R + 'static,
154 R: glib::value::ValueType,
155 {
156 crate::ClosureExpression::with_callback([self], f)
157 }
158}
159
160impl std::fmt::Debug for Expression {
161 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
162 f.debug_struct("Expression")
163 .field("value_type", &self.value_type())
164 .field("is_static", &self.is_static())
165 .finish()
166 }
167}
168
169impl glib::value::ValueType for Expression {
170 type Type = Self;
171}
172
173unsafe impl<'a> glib::value::FromValue<'a> for Expression {
174 type Checker = glib::value::GenericValueTypeOrNoneChecker<Self>;
175
176 #[inline]
177 unsafe fn from_value(value: &'a glib::Value) -> Self {
178 unsafe {
179 skip_assert_initialized!();
180 from_glib_full(crate::ffi::gtk_value_dup_expression(value.to_glib_none().0))
181 }
182 }
183}
184
185impl glib::value::ToValue for Expression {
186 #[inline]
187 fn to_value(&self) -> glib::Value {
188 let mut value = glib::Value::for_value_type::<Self>();
189 unsafe {
190 crate::ffi::gtk_value_set_expression(value.to_glib_none_mut().0, self.to_glib_none().0)
191 }
192 value
193 }
194
195 #[inline]
196 fn value_type(&self) -> glib::Type {
197 Self::static_type()
198 }
199}
200
201impl glib::value::ToValueOptional for Expression {
202 fn to_value_optional(s: Option<&Self>) -> glib::Value {
203 skip_assert_initialized!();
204 let mut value = glib::Value::for_value_type::<Self>();
205 unsafe {
206 crate::ffi::gtk_value_set_expression(value.to_glib_none_mut().0, s.to_glib_none().0)
207 }
208 value
209 }
210}
211
212impl From<Expression> for glib::Value {
213 fn from(e: Expression) -> Self {
214 skip_assert_initialized!();
215 let mut value = glib::Value::for_value_type::<Expression>();
216 unsafe {
217 crate::ffi::gtk_value_take_expression(value.to_glib_none_mut().0, e.into_glib_ptr())
218 }
219 value
220 }
221}
222
223pub trait GObjectPropertyExpressionExt: IsA<glib::Object> {
243 fn property_expression(&self, property_name: &str) -> crate::PropertyExpression {
246 let obj_expr = crate::ConstantExpression::new(self);
247 crate::PropertyExpression::new(Self::static_type(), Some(&obj_expr), property_name)
248 }
249
250 fn property_expression_weak(&self, property_name: &str) -> crate::PropertyExpression {
254 let obj_expr = crate::ObjectExpression::new(self);
255 crate::PropertyExpression::new(Self::static_type(), Some(&obj_expr), property_name)
256 }
257
258 fn this_expression(property_name: &str) -> crate::PropertyExpression {
261 skip_assert_initialized!();
262 crate::PropertyExpression::new(Self::static_type(), Expression::NONE, property_name)
263 }
264}
265
266impl<O: IsA<glib::Object>> GObjectPropertyExpressionExt for O {}
267
268macro_rules! define_expression {
269 ($rust_type:ident, $ffi_type:path) => {
270 impl std::ops::Deref for $rust_type {
271 type Target = crate::Expression;
272
273 #[inline]
274 fn deref(&self) -> &Self::Target {
275 unsafe { &*(self as *const $rust_type as *const crate::Expression) }
276 }
277 }
278
279 impl AsRef<crate::Expression> for $rust_type {
280 #[inline]
281 fn as_ref(&self) -> &crate::Expression {
282 self.upcast_ref()
283 }
284 }
285
286 impl $rust_type {
287 #[inline]
288 pub fn upcast(self) -> crate::Expression {
289 unsafe { std::mem::transmute(self) }
290 }
291
292 #[inline]
293 pub fn upcast_ref(&self) -> &crate::Expression {
294 self
295 }
296 }
297
298 #[doc(hidden)]
299 impl<'a> ToGlibPtr<'a, *const crate::ffi::GtkExpression> for $rust_type {
300 type Storage =
301 ::std::marker::PhantomData<&'a $crate::glib::shared::Shared<$ffi_type, $rust_type>>;
302
303 #[inline]
304 fn to_glib_none(
305 &'a self,
306 ) -> $crate::glib::translate::Stash<'a, *const crate::ffi::GtkExpression, Self> {
307 let stash =
308 $crate::glib::translate::ToGlibPtr::<*const $ffi_type>::to_glib_none(self);
309 $crate::glib::translate::Stash(stash.0 as *const _, stash.1)
310 }
311
312 #[inline]
313 fn to_glib_full(&self) -> *const crate::ffi::GtkExpression {
314 $crate::glib::translate::ToGlibPtr::<*const $ffi_type>::to_glib_full(self)
315 as *const _
316 }
317 }
318
319 #[doc(hidden)]
320 impl<'a> ToGlibPtr<'a, *mut crate::ffi::GtkExpression> for $rust_type {
321 type Storage =
322 ::std::marker::PhantomData<&'a $crate::glib::shared::Shared<$ffi_type, $rust_type>>;
323
324 #[inline]
325 fn to_glib_none(
326 &'a self,
327 ) -> $crate::glib::translate::Stash<'a, *mut crate::ffi::GtkExpression, Self> {
328 let stash =
329 $crate::glib::translate::ToGlibPtr::<*mut $ffi_type>::to_glib_none(self);
330 $crate::glib::translate::Stash(stash.0 as *mut _, stash.1)
331 }
332
333 #[inline]
334 fn to_glib_full(&self) -> *mut crate::ffi::GtkExpression {
335 $crate::glib::translate::ToGlibPtr::<*mut $ffi_type>::to_glib_full(self) as *mut _
336 }
337 }
338
339 #[doc(hidden)]
340 impl IntoGlibPtr<*mut crate::ffi::GtkExpression> for $rust_type {
341 #[inline]
342 fn into_glib_ptr(self) -> *mut crate::ffi::GtkExpression {
343 let s = std::mem::ManuallyDrop::new(self);
344 s.to_glib_none().0
345 }
346 }
347
348 #[doc(hidden)]
349 impl IntoGlibPtr<*const crate::ffi::GtkExpression> for $rust_type {
350 #[inline]
351 fn into_glib_ptr(self) -> *const crate::ffi::GtkExpression {
352 let s = std::mem::ManuallyDrop::new(self);
353 s.to_glib_none().0
354 }
355 }
356
357 #[doc(hidden)]
358 impl FromGlibPtrFull<*mut crate::ffi::GtkExpression> for $rust_type {
359 #[inline]
360 unsafe fn from_glib_full(ptr: *mut crate::ffi::GtkExpression) -> Self {
361 unsafe { from_glib_full(ptr as *mut $ffi_type) }
362 }
363 }
364
365 unsafe impl crate::expression::IsExpression for $rust_type {}
366
367 impl glib::value::ValueType for $rust_type {
368 type Type = Self;
369 }
370
371 unsafe impl<'a> glib::value::FromValue<'a> for $rust_type {
372 type Checker = glib::value::GenericValueTypeOrNoneChecker<Self>;
373
374 #[inline]
375 unsafe fn from_value(value: &'a glib::Value) -> Self {
376 unsafe {
377 skip_assert_initialized!();
378 from_glib_full(crate::ffi::gtk_value_dup_expression(value.to_glib_none().0))
379 }
380 }
381 }
382
383 impl glib::value::ToValue for $rust_type {
384 #[inline]
385 fn to_value(&self) -> glib::Value {
386 let mut value = glib::Value::for_value_type::<Self>();
387 unsafe {
388 crate::ffi::gtk_value_set_expression(
389 value.to_glib_none_mut().0,
390 self.as_ptr() as *mut _,
391 )
392 }
393 value
394 }
395
396 #[inline]
397 fn value_type(&self) -> glib::Type {
398 use glib::prelude::StaticType;
399 Self::static_type()
400 }
401 }
402
403 impl glib::value::ToValueOptional for $rust_type {
404 #[inline]
405 fn to_value_optional(s: Option<&Self>) -> glib::Value {
406 skip_assert_initialized!();
407 let mut value = glib::Value::for_value_type::<Self>();
408 unsafe {
409 crate::ffi::gtk_value_set_expression(
410 value.to_glib_none_mut().0,
411 s.map(|s| s.as_ptr()).unwrap_or(std::ptr::null_mut()) as *mut _,
412 )
413 }
414 value
415 }
416 }
417
418 impl From<$rust_type> for glib::Value {
419 fn from(e: $rust_type) -> Self {
420 skip_assert_initialized!();
421 let mut value = glib::Value::for_value_type::<$rust_type>();
422 unsafe {
423 crate::ffi::gtk_value_take_expression(
424 value.to_glib_none_mut().0,
425 e.into_glib_ptr(),
426 )
427 }
428 value
429 }
430 }
431
432 impl glib::HasParamSpec for $rust_type {
433 type ParamSpec = crate::ParamSpecExpression;
434
435 type SetValue = $rust_type;
436
437 type BuilderFn = for<'a> fn(&'a str) -> crate::builders::ParamSpecExpressionBuilder<'a>;
438
439 fn param_spec_builder() -> Self::BuilderFn {
440 Self::ParamSpec::builder
441 }
442 }
443 };
444}