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::{gobject_ffi, shared::Shared, translate::*, ParamSpec, Value};
6
7use crate::{ffi, prelude::*, Expression, ParamSpecExpression};
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    unsafe 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    unsafe 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        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        let ptr = gobject_ffi::g_value_dup_param(value.to_glib_none().0);
215        debug_assert!(!ptr.is_null());
216        from_glib_full(ptr)
217    }
218}
219
220#[doc(hidden)]
221impl ToValue for ParamSpecExpression {
222    #[inline]
223    fn to_value(&self) -> Value {
224        unsafe {
225            let mut value = Value::for_value_type::<Self>();
226            gobject_ffi::g_value_take_param(
227                value.to_glib_none_mut().0,
228                ToGlibPtr::<*mut _>::to_glib_full(self) as *mut _,
229            );
230            value
231        }
232    }
233
234    #[inline]
235    fn value_type(&self) -> glib::Type {
236        Self::static_type()
237    }
238}
239
240#[doc(hidden)]
241impl glib::value::ToValueOptional for ParamSpecExpression {
242    #[inline]
243    fn to_value_optional(s: Option<&Self>) -> Value {
244        assert_initialized_main_thread!();
245        let mut value = Value::for_value_type::<Self>();
246        unsafe {
247            gobject_ffi::g_value_take_param(
248                value.to_glib_none_mut().0,
249                ToGlibPtr::<*mut _>::to_glib_full(&s) as *mut _,
250            );
251        }
252
253        value
254    }
255}
256
257#[doc(hidden)]
258impl From<ParamSpecExpression> for Value {
259    fn from(s: ParamSpecExpression) -> Self {
260        assert_initialized_main_thread!();
261        unsafe {
262            let mut value = Value::from_type(ParamSpecExpression::static_type());
263            gobject_ffi::g_value_take_param(value.to_glib_none_mut().0, s.into_glib_ptr());
264            value
265        }
266    }
267}
268
269#[cfg(test)]
270mod tests {
271    use super::*;
272    use crate as gtk4;
273
274    #[test]
275    fn paramspec_expression() {
276        let pspec = ParamSpecExpression::new(
277            "expression",
278            None::<&str>,
279            None::<&str>,
280            glib::ParamFlags::CONSTRUCT_ONLY | glib::ParamFlags::READABLE,
281        );
282
283        let expr_pspec = pspec.downcast::<ParamSpecExpression>();
284        assert!(expr_pspec.is_ok());
285    }
286
287    #[test]
288    fn paramspec_expression_builder() {
289        let pspec = ParamSpecExpression::builder("expression")
290            .construct_only()
291            .read_only()
292            .build();
293
294        assert_eq!(
295            pspec.flags(),
296            glib::ParamFlags::CONSTRUCT_ONLY | glib::ParamFlags::READABLE
297        );
298    }
299}