Skip to main content

gtk4/
param_spec_expression.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::marker::PhantomData;
4
5use glib::{ParamSpec, Value, gobject_ffi, shared::Shared, translate::*};
6
7use crate::{Expression, ParamSpecExpression, ffi, prelude::*};
8
9impl HasParamSpec for Expression {
10    type ParamSpec = ParamSpecExpression;
11
12    type SetValue = Expression;
13
14    type BuilderFn = for<'a> fn(&'a str) -> ParamSpecExpressionBuilder<'a>;
15
16    fn param_spec_builder() -> Self::BuilderFn {
17        Self::ParamSpec::builder
18    }
19}
20
21impl std::fmt::Debug for ParamSpecExpression {
22    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
23        f.write_str("ParamSpecExpression")
24    }
25}
26
27impl std::ops::Deref for ParamSpecExpression {
28    type Target = ParamSpec;
29
30    #[inline]
31    fn deref(&self) -> &Self::Target {
32        unsafe { &*(self as *const ParamSpecExpression as *const ParamSpec) }
33    }
34}
35
36unsafe impl glib::ParamSpecType for ParamSpecExpression {}
37
38#[doc(hidden)]
39impl<'a> ToGlibPtr<'a, *const gobject_ffi::GParamSpec> for ParamSpecExpression {
40    type Storage = PhantomData<&'a Shared<ffi::GtkParamSpecExpression, ParamSpecExpression>>;
41
42    #[inline]
43    fn to_glib_none(&'a self) -> Stash<'a, *const gobject_ffi::GParamSpec, Self> {
44        let stash = ToGlibPtr::<*const ffi::GtkParamSpecExpression>::to_glib_none(self);
45        Stash(stash.0 as *const _, stash.1)
46    }
47
48    #[inline]
49    fn to_glib_full(&self) -> *const gobject_ffi::GParamSpec {
50        ToGlibPtr::<*const ffi::GtkParamSpecExpression>::to_glib_full(self) as *const _
51    }
52}
53
54#[doc(hidden)]
55impl<'a> ToGlibPtr<'a, *mut gobject_ffi::GParamSpec> for ParamSpecExpression {
56    type Storage = PhantomData<&'a Shared<ffi::GtkParamSpecExpression, ParamSpecExpression>>;
57
58    #[inline]
59    fn to_glib_none(&'a self) -> Stash<'a, *mut gobject_ffi::GParamSpec, Self> {
60        let stash = ToGlibPtr::<*mut ffi::GtkParamSpecExpression>::to_glib_none(self);
61        Stash(stash.0 as *mut _, stash.1)
62    }
63
64    #[inline]
65    fn to_glib_full(&self) -> *mut gobject_ffi::GParamSpec {
66        ToGlibPtr::<*mut ffi::GtkParamSpecExpression>::to_glib_full(self) as *mut _
67    }
68}
69
70#[doc(hidden)]
71impl IntoGlibPtr<*mut gobject_ffi::GParamSpec> for ParamSpecExpression {
72    #[inline]
73    fn into_glib_ptr(self) -> *mut gobject_ffi::GParamSpec {
74        let s = std::mem::ManuallyDrop::new(self);
75        s.to_glib_none().0
76    }
77}
78
79#[doc(hidden)]
80impl IntoGlibPtr<*const gobject_ffi::GParamSpec> for ParamSpecExpression {
81    #[inline]
82    fn into_glib_ptr(self) -> *const gobject_ffi::GParamSpec {
83        let s = std::mem::ManuallyDrop::new(self);
84        s.to_glib_none().0
85    }
86}
87
88#[doc(hidden)]
89impl FromGlibPtrFull<*mut gobject_ffi::GParamSpec> for ParamSpecExpression {
90    #[inline]
91    unsafe fn from_glib_full(ptr: *mut gobject_ffi::GParamSpec) -> Self {
92        unsafe { from_glib_full(ptr as *mut ffi::GtkParamSpecExpression) }
93    }
94}
95
96impl ParamSpecExpression {
97    #[allow(clippy::new_ret_no_self)]
98    #[doc(alias = "gtk_param_spec_expression")]
99    #[deprecated = "Use builder() instead"]
100    pub fn new(
101        name: impl IntoGStr,
102        nick: impl IntoOptionalGStr,
103        blurb: impl IntoOptionalGStr,
104        flags: glib::ParamFlags,
105    ) -> ParamSpec {
106        assert_initialized_main_thread!();
107        unsafe {
108            name.run_with_gstr(|name| {
109                nick.run_with_gstr(|nick| {
110                    blurb.run_with_gstr(|blurb| {
111                        from_glib_none(ffi::gtk_param_spec_expression(
112                            name.as_ptr(),
113                            nick.to_glib_none().0,
114                            blurb.to_glib_none().0,
115                            flags.into_glib(),
116                        ))
117                    })
118                })
119            })
120        }
121    }
122
123    // rustdoc-stripper-ignore-next
124    /// Creates a new builder-pattern struct instance to construct
125    /// [`ParamSpecExpression`] objects.
126    ///
127    /// This method returns an instance of
128    /// [`ParamSpecExpressionBuilder`](crate::builders::ParamSpecExpressionBuilder)
129    /// which can be used to create [`ParamSpecExpression`] objects.
130    pub fn builder(name: &str) -> ParamSpecExpressionBuilder<'_> {
131        assert_initialized_main_thread!();
132        ParamSpecExpressionBuilder::new(name)
133    }
134
135    pub fn upcast(self) -> ParamSpec {
136        unsafe { from_glib_full(IntoGlibPtr::<*mut _>::into_glib_ptr(self)) }
137    }
138
139    pub fn upcast_ref(&self) -> &ParamSpec {
140        self
141    }
142}
143
144#[derive(Default)]
145#[must_use]
146// rustdoc-stripper-ignore-next
147/// A [builder-pattern] type to construct [`ParamSpecExpression`] objects.
148///
149/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html
150pub struct ParamSpecExpressionBuilder<'a> {
151    name: &'a str,
152    nick: Option<&'a str>,
153    blurb: Option<&'a str>,
154    flags: glib::ParamFlags,
155}
156
157impl<'a> ParamSpecBuilderExt<'a> for ParamSpecExpressionBuilder<'a> {
158    // rustdoc-stripper-ignore-next
159    /// Default: `self.name`
160    fn set_nick(&mut self, nick: Option<&'a str>) {
161        self.nick = nick;
162    }
163
164    // rustdoc-stripper-ignore-next
165    /// Default: `self.name`
166    fn set_blurb(&mut self, blurb: Option<&'a str>) {
167        self.blurb = blurb;
168    }
169
170    // rustdoc-stripper-ignore-next
171    /// Default: `glib::ParamFlags::READWRITE`
172    fn set_flags(&mut self, flags: glib::ParamFlags) {
173        self.flags = flags;
174    }
175
176    // rustdoc-stripper-ignore-next
177    /// Implementation detail.
178    fn current_flags(&self) -> glib::ParamFlags {
179        self.flags
180    }
181}
182
183impl<'a> ParamSpecExpressionBuilder<'a> {
184    fn new(name: &'a str) -> Self {
185        assert_initialized_main_thread!();
186        Self {
187            name,
188            ..Default::default()
189        }
190    }
191
192    #[must_use]
193    // rustdoc-stripper-ignore-next
194    /// Build the [`ParamSpecExpression`].
195    pub fn build(self) -> ParamSpec {
196        ParamSpecExpression::new(self.name, self.nick, self.blurb, self.flags)
197    }
198}
199
200#[doc(hidden)]
201impl ValueType for ParamSpecExpression {
202    type Type = ParamSpecExpression;
203}
204
205#[doc(hidden)]
206impl glib::value::ValueTypeOptional for ParamSpecExpression {}
207
208#[doc(hidden)]
209unsafe impl<'a> glib::value::FromValue<'a> for ParamSpecExpression {
210    type Checker = glib::value::GenericValueTypeOrNoneChecker<Self>;
211
212    #[inline]
213    unsafe fn from_value(value: &'a Value) -> Self {
214        unsafe {
215            let ptr = gobject_ffi::g_value_dup_param(value.to_glib_none().0);
216            debug_assert!(!ptr.is_null());
217            from_glib_full(ptr)
218        }
219    }
220}
221
222#[doc(hidden)]
223impl ToValue for ParamSpecExpression {
224    #[inline]
225    fn to_value(&self) -> Value {
226        unsafe {
227            let mut value = Value::for_value_type::<Self>();
228            gobject_ffi::g_value_take_param(
229                value.to_glib_none_mut().0,
230                ToGlibPtr::<*mut _>::to_glib_full(self) as *mut _,
231            );
232            value
233        }
234    }
235
236    #[inline]
237    fn value_type(&self) -> glib::Type {
238        Self::static_type()
239    }
240}
241
242#[doc(hidden)]
243impl glib::value::ToValueOptional for ParamSpecExpression {
244    #[inline]
245    fn to_value_optional(s: Option<&Self>) -> Value {
246        assert_initialized_main_thread!();
247        let mut value = Value::for_value_type::<Self>();
248        unsafe {
249            gobject_ffi::g_value_take_param(
250                value.to_glib_none_mut().0,
251                ToGlibPtr::<*mut _>::to_glib_full(&s) as *mut _,
252            );
253        }
254
255        value
256    }
257}
258
259#[doc(hidden)]
260impl From<ParamSpecExpression> for Value {
261    fn from(s: ParamSpecExpression) -> Self {
262        assert_initialized_main_thread!();
263        unsafe {
264            let mut value = Value::from_type(ParamSpecExpression::static_type());
265            gobject_ffi::g_value_take_param(value.to_glib_none_mut().0, s.into_glib_ptr());
266            value
267        }
268    }
269}
270
271#[cfg(test)]
272mod tests {
273    use super::*;
274    use crate as gtk4;
275
276    #[test]
277    fn paramspec_expression() {
278        let pspec = ParamSpecExpression::new(
279            "expression",
280            None::<&str>,
281            None::<&str>,
282            glib::ParamFlags::CONSTRUCT_ONLY | glib::ParamFlags::READABLE,
283        );
284
285        let expr_pspec = pspec.downcast::<ParamSpecExpression>();
286        assert!(expr_pspec.is_ok());
287    }
288
289    #[test]
290    fn paramspec_expression_builder() {
291        let pspec = ParamSpecExpression::builder("expression")
292            .construct_only()
293            .read_only()
294            .build();
295
296        assert_eq!(
297            pspec.flags(),
298            glib::ParamFlags::CONSTRUCT_ONLY | glib::ParamFlags::READABLE
299        );
300    }
301}