glib/
param_spec.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{
4    char::CharTryFromError,
5    ffi::CStr,
6    num::{NonZeroI32, NonZeroI64, NonZeroI8, NonZeroU32, NonZeroU64, NonZeroU8},
7    path::{Path, PathBuf},
8};
9
10use crate::{
11    ffi, gobject_ffi,
12    object::{Interface, InterfaceRef, IsClass, IsInterface, ObjectClass},
13    prelude::*,
14    translate::*,
15    utils::is_canonical_pspec_name,
16    Object, ParamFlags, Type, Value,
17};
18// Can't use get_type here as this is not a boxed type but another fundamental type
19wrapper! {
20    /// `GParamSpec` encapsulates the metadata required to specify parameters, such as `GObject` properties.
21    ///
22    /// ## Parameter names
23    ///
24    /// A property name consists of one or more segments consisting of ASCII letters
25    /// and digits, separated by either the `-` or `_` character. The first
26    /// character of a property name must be a letter. These are the same rules as
27    /// for signal naming (see [func[`Object`][crate::Object]]).
28    ///
29    /// When creating and looking up a `GParamSpec`, either separator can be
30    /// used, but they cannot be mixed. Using `-` is considerably more
31    /// efficient, and is the ‘canonical form’. Using `_` is discouraged.
32    ///
33    /// This is an Abstract Base Class, you cannot instantiate it.
34    // rustdoc-stripper-ignore-next-stop
35    /// `GParamSpec` encapsulates the metadata required to specify parameters, such as `GObject` properties.
36    ///
37    /// ## Parameter names
38    ///
39    /// A property name consists of one or more segments consisting of ASCII letters
40    /// and digits, separated by either the `-` or `_` character. The first
41    /// character of a property name must be a letter. These are the same rules as
42    /// for signal naming (see [func[`Object`][crate::Object]]).
43    ///
44    /// When creating and looking up a `GParamSpec`, either separator can be
45    /// used, but they cannot be mixed. Using `-` is considerably more
46    /// efficient, and is the ‘canonical form’. Using `_` is discouraged.
47    ///
48    /// This is an Abstract Base Class, you cannot instantiate it.
49    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
50    #[doc(alias = "GParamSpec")]
51    pub struct ParamSpec(Shared<gobject_ffi::GParamSpec>);
52
53    match fn {
54        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr),
55        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr),
56    }
57}
58
59impl StaticType for ParamSpec {
60    #[inline]
61    fn static_type() -> Type {
62        unsafe { from_glib(gobject_ffi::G_TYPE_PARAM) }
63    }
64}
65
66#[doc(hidden)]
67impl crate::value::ValueType for ParamSpec {
68    type Type = ParamSpec;
69}
70
71#[doc(hidden)]
72impl crate::value::ValueTypeOptional for ParamSpec {}
73
74#[doc(hidden)]
75unsafe impl<'a> crate::value::FromValue<'a> for ParamSpec {
76    type Checker = crate::value::GenericValueTypeOrNoneChecker<Self>;
77
78    unsafe fn from_value(value: &'a crate::Value) -> Self {
79        let ptr = gobject_ffi::g_value_dup_param(value.to_glib_none().0);
80        debug_assert!(!ptr.is_null());
81        from_glib_full(ptr)
82    }
83}
84
85#[doc(hidden)]
86unsafe impl<'a> crate::value::FromValue<'a> for &'a ParamSpec {
87    type Checker = crate::value::GenericValueTypeOrNoneChecker<Self>;
88
89    unsafe fn from_value(value: &'a crate::Value) -> Self {
90        debug_assert_eq!(
91            std::mem::size_of::<Self>(),
92            std::mem::size_of::<crate::ffi::gpointer>()
93        );
94        let value = &*(value as *const crate::Value as *const crate::gobject_ffi::GValue);
95        let ptr = &value.data[0].v_pointer as *const crate::ffi::gpointer
96            as *const *const gobject_ffi::GParamSpec;
97        debug_assert!(!(*ptr).is_null());
98        &*(ptr as *const ParamSpec)
99    }
100}
101
102#[doc(hidden)]
103impl crate::value::ToValue for ParamSpec {
104    fn to_value(&self) -> crate::Value {
105        unsafe {
106            let mut value = crate::Value::from_type_unchecked(ParamSpec::static_type());
107            gobject_ffi::g_value_take_param(value.to_glib_none_mut().0, self.to_glib_full());
108            value
109        }
110    }
111
112    fn value_type(&self) -> crate::Type {
113        ParamSpec::static_type()
114    }
115}
116
117#[doc(hidden)]
118impl From<ParamSpec> for crate::Value {
119    #[inline]
120    fn from(s: ParamSpec) -> Self {
121        unsafe {
122            let mut value = crate::Value::from_type_unchecked(ParamSpec::static_type());
123            gobject_ffi::g_value_take_param(value.to_glib_none_mut().0, s.into_glib_ptr());
124            value
125        }
126    }
127}
128
129#[doc(hidden)]
130impl crate::value::ToValueOptional for ParamSpec {
131    fn to_value_optional(s: Option<&Self>) -> crate::Value {
132        let mut value = crate::Value::for_value_type::<Self>();
133        unsafe {
134            gobject_ffi::g_value_take_param(value.to_glib_none_mut().0, s.to_glib_full());
135        }
136
137        value
138    }
139}
140
141impl AsRef<ParamSpec> for ParamSpec {
142    #[inline]
143    fn as_ref(&self) -> &ParamSpec {
144        self
145    }
146}
147
148unsafe impl Send for ParamSpec {}
149unsafe impl Sync for ParamSpec {}
150
151impl ParamSpec {
152    pub fn downcast<T: ParamSpecType>(self) -> Result<T, ParamSpec> {
153        unsafe {
154            if self.type_() == T::static_type() {
155                Ok(from_glib_full(self.into_glib_ptr()))
156            } else {
157                Err(self)
158            }
159        }
160    }
161
162    pub fn downcast_ref<T: ParamSpecType>(&self) -> Option<&T> {
163        unsafe {
164            if self.type_() == T::static_type() {
165                Some(&*(self as *const ParamSpec as *const T))
166            } else {
167                None
168            }
169        }
170    }
171
172    #[doc(alias = "get_type")]
173    #[inline]
174    pub fn type_(&self) -> Type {
175        unsafe {
176            from_glib(
177                (*(*(<Self as ToGlibPtr<*const _>>::to_glib_none(self).0))
178                    .g_type_instance
179                    .g_class)
180                    .g_type,
181            )
182        }
183    }
184
185    #[inline]
186    pub fn is<T: StaticType>(&self) -> bool {
187        self.type_().is_a(T::static_type())
188    }
189
190    #[doc(alias = "get_value_type")]
191    #[inline]
192    pub fn value_type(&self) -> crate::Type {
193        unsafe { from_glib((*(<Self as ToGlibPtr<*const _>>::to_glib_none(self).0)).value_type) }
194    }
195
196    #[cfg(feature = "v2_74")]
197    #[cfg_attr(docsrs, doc(cfg(feature = "v2_74")))]
198    #[doc(alias = "g_param_value_is_valid")]
199    #[inline]
200    pub fn value_is_valid(&self, value: &Value) -> bool {
201        unsafe {
202            from_glib(gobject_ffi::g_param_value_is_valid(
203                self.to_glib_none().0,
204                value.to_glib_none().0,
205            ))
206        }
207    }
208
209    #[doc(alias = "get_owner_type")]
210    #[inline]
211    pub fn owner_type(&self) -> crate::Type {
212        unsafe { from_glib((*(<Self as ToGlibPtr<*const _>>::to_glib_none(self).0)).owner_type) }
213    }
214
215    #[doc(alias = "get_flags")]
216    #[inline]
217    pub fn flags(&self) -> ParamFlags {
218        unsafe { from_glib((*(<Self as ToGlibPtr<*const _>>::to_glib_none(self).0)).flags) }
219    }
220
221    /// Get the short description of a [`ParamSpec`][crate::ParamSpec].
222    ///
223    /// # Returns
224    ///
225    /// the short description of `self`.
226    // rustdoc-stripper-ignore-next-stop
227    /// Get the short description of a [`ParamSpec`][crate::ParamSpec].
228    ///
229    /// # Returns
230    ///
231    /// the short description of `self`.
232    #[doc(alias = "g_param_spec_get_blurb")]
233    #[doc(alias = "get_blurb")]
234    #[inline]
235    pub fn blurb(&self) -> Option<&str> {
236        unsafe {
237            let ptr = gobject_ffi::g_param_spec_get_blurb(self.to_glib_none().0);
238            if ptr.is_null() {
239                None
240            } else {
241                CStr::from_ptr(ptr).to_str().ok()
242            }
243        }
244    }
245
246    /// Gets the default value of `self` as a pointer to a [`Value`][crate::Value].
247    ///
248    /// The [`Value`][crate::Value] will remain valid for the life of `self`.
249    ///
250    /// # Returns
251    ///
252    /// a pointer to a [`Value`][crate::Value] which must not be modified
253    // rustdoc-stripper-ignore-next-stop
254    /// Gets the default value of `self` as a pointer to a [`Value`][crate::Value].
255    ///
256    /// The [`Value`][crate::Value] will remain valid for the life of `self`.
257    ///
258    /// # Returns
259    ///
260    /// a pointer to a [`Value`][crate::Value] which must not be modified
261    #[doc(alias = "g_param_spec_get_default_value")]
262    #[doc(alias = "get_default_value")]
263    #[inline]
264    pub fn default_value(&self) -> &Value {
265        unsafe {
266            &*(gobject_ffi::g_param_spec_get_default_value(self.to_glib_none().0)
267                as *const crate::Value)
268        }
269    }
270
271    /// Get the name of a [`ParamSpec`][crate::ParamSpec].
272    ///
273    /// The name is always an "interned" string (as per `g_intern_string()`).
274    /// This allows for pointer-value comparisons.
275    ///
276    /// # Returns
277    ///
278    /// the name of `self`.
279    // rustdoc-stripper-ignore-next-stop
280    /// Get the name of a [`ParamSpec`][crate::ParamSpec].
281    ///
282    /// The name is always an "interned" string (as per `g_intern_string()`).
283    /// This allows for pointer-value comparisons.
284    ///
285    /// # Returns
286    ///
287    /// the name of `self`.
288    #[doc(alias = "g_param_spec_get_name")]
289    #[doc(alias = "get_name")]
290    #[inline]
291    pub fn name<'a>(&self) -> &'a str {
292        unsafe {
293            CStr::from_ptr(gobject_ffi::g_param_spec_get_name(self.to_glib_none().0))
294                .to_str()
295                .unwrap()
296        }
297    }
298
299    /// Gets the GQuark for the name.
300    ///
301    /// # Returns
302    ///
303    /// the GQuark for `self`->name.
304    // rustdoc-stripper-ignore-next-stop
305    /// Gets the GQuark for the name.
306    ///
307    /// # Returns
308    ///
309    /// the GQuark for `self`->name.
310    #[doc(alias = "g_param_spec_get_name_quark")]
311    #[doc(alias = "get_name_quark")]
312    #[inline]
313    pub fn name_quark(&self) -> crate::Quark {
314        unsafe {
315            from_glib(gobject_ffi::g_param_spec_get_name_quark(
316                self.to_glib_none().0,
317            ))
318        }
319    }
320
321    // rustdoc-stripper-ignore-next
322    /// Returns the nickname of this `ParamSpec`.
323    ///
324    /// If this `ParamSpec` does not have a nickname, the nickname of its redirect target is returned if it has one.
325    /// Otherwise, `self.name()` is returned.
326    // rustdoc-stripper-ignore-next-stop
327    /// Get the nickname of a [`ParamSpec`][crate::ParamSpec].
328    ///
329    /// # Returns
330    ///
331    /// the nickname of `self`.
332    // rustdoc-stripper-ignore-next-stop
333    /// Get the nickname of a [`ParamSpec`][crate::ParamSpec].
334    ///
335    /// # Returns
336    ///
337    /// the nickname of `self`.
338    #[doc(alias = "g_param_spec_get_nick")]
339    #[doc(alias = "get_nick")]
340    #[inline]
341    pub fn nick(&self) -> &str {
342        unsafe {
343            CStr::from_ptr(gobject_ffi::g_param_spec_get_nick(self.to_glib_none().0))
344                .to_str()
345                .unwrap()
346        }
347    }
348
349    //pub fn get_qdata(&self, quark: /*Ignored*/glib::Quark) -> /*Unimplemented*/Option<Fundamental: Pointer> {
350    //    unsafe { TODO: call gobject_ffi::g_param_spec_get_qdata() }
351    //}
352
353    /// contains
354    /// references to other environment variables, they are expanded.
355    /// ## `variable`
356    /// the environment variable to get
357    ///
358    /// # Returns
359    ///
360    /// the value of the environment variable, or [`None`] if
361    ///     the environment variable is not found. The returned string
362    ///     may be overwritten by the next call to g_getenv(), g_setenv()
363    ///     or g_unsetenv().
364    // rustdoc-stripper-ignore-next-stop
365    /// If the paramspec redirects operations to another paramspec,
366    /// returns that paramspec. Redirect is used typically for
367    /// providing a new implementation of a property in a derived
368    /// type while preserving all the properties from the parent
369    /// type. Redirection is established by creating a property
370    /// of type [`ParamSpecOverride`][crate::ParamSpecOverride]. See `g_object_class_override_property()`
371    /// for an example of the use of this capability.
372    ///
373    /// # Returns
374    ///
375    /// paramspec to which requests on this
376    ///  paramspec should be redirected, or [`None`] if none.
377    #[doc(alias = "g_param_spec_get_redirect_target")]
378    #[doc(alias = "get_redirect_target")]
379    #[inline]
380    pub fn redirect_target(&self) -> Option<ParamSpec> {
381        unsafe {
382            from_glib_none(gobject_ffi::g_param_spec_get_redirect_target(
383                self.to_glib_none().0,
384            ))
385        }
386    }
387
388    //pub fn set_qdata(&self, quark: /*Ignored*/glib::Quark, data: Option</*Unimplemented*/Fundamental: Pointer>) {
389    //    unsafe { TODO: call gobject_ffi::g_param_spec_set_qdata() }
390    //}
391
392    //pub fn set_qdata_full(&self, quark: /*Ignored*/glib::Quark, data: Option</*Unimplemented*/Fundamental: Pointer>, destroy: /*Unknown conversion*//*Unimplemented*/DestroyNotify) {
393    //    unsafe { TODO: call gobject_ffi::g_param_spec_set_qdata_full() }
394    //}
395
396    //pub fn steal_qdata(&self, quark: /*Ignored*/glib::Quark) -> /*Unimplemented*/Option<Fundamental: Pointer> {
397    //    unsafe { TODO: call gobject_ffi::g_param_spec_steal_qdata() }
398    //}
399
400    /// Validate a property name for a [`ParamSpec`][crate::ParamSpec]. This can be useful for
401    /// dynamically-generated properties which need to be validated at run-time
402    /// before actually trying to create them.
403    ///
404    /// See [canonical parameter names][class[`Object`][crate::Object]`parameter`-names]
405    /// for details of the rules for valid names.
406    /// ## `name`
407    /// the canonical name of the property
408    ///
409    /// # Returns
410    ///
411    /// [`true`] if `name` is a valid property name, [`false`] otherwise.
412    // rustdoc-stripper-ignore-next-stop
413    /// Validate a property name for a [`ParamSpec`][crate::ParamSpec]. This can be useful for
414    /// dynamically-generated properties which need to be validated at run-time
415    /// before actually trying to create them.
416    ///
417    /// See [canonical parameter names][class[`Object`][crate::Object]`parameter`-names]
418    /// for details of the rules for valid names.
419    /// ## `name`
420    /// the canonical name of the property
421    ///
422    /// # Returns
423    ///
424    /// [`true`] if `name` is a valid property name, [`false`] otherwise.
425    #[cfg(feature = "v2_66")]
426    #[cfg_attr(docsrs, doc(cfg(feature = "v2_66")))]
427    #[doc(alias = "g_param_spec_is_valid_name")]
428    #[inline]
429    pub fn is_valid_name(name: &str) -> bool {
430        unsafe {
431            from_glib(gobject_ffi::g_param_spec_is_valid_name(
432                name.to_glib_none().0,
433            ))
434        }
435    }
436}
437
438pub unsafe trait ParamSpecType:
439    StaticType + FromGlibPtrFull<*mut gobject_ffi::GParamSpec> + 'static
440{
441}
442
443macro_rules! define_param_spec {
444    ($rust_type:ident, $ffi_type:path, $type_name:literal) => {
445        impl StaticType for $rust_type {
446            #[inline]
447            fn static_type() -> Type {
448                // Instead of using the direct reference to the `g_param_spec_types` table, we
449                // use `g_type_from_name` to query for each of the param spec types. This is
450                // because rust currently has issues properly linking variables from external
451                // libraries without using a `#[link]` attribute.
452                unsafe { from_glib(gobject_ffi::g_type_from_name(concat!($type_name, "\0").as_ptr() as *const _)) }
453            }
454        }
455
456        #[doc(hidden)]
457        impl crate::value::ValueType for $rust_type {
458            type Type = $rust_type;
459        }
460
461        #[doc(hidden)]
462        impl crate::value::ValueTypeOptional for $rust_type {}
463
464        #[doc(hidden)]
465        unsafe impl<'a> crate::value::FromValue<'a> for $rust_type {
466            type Checker = $crate::value::GenericValueTypeOrNoneChecker<Self>;
467
468            unsafe fn from_value(value: &'a crate::Value) -> Self {
469                let ptr = gobject_ffi::g_value_dup_param(value.to_glib_none().0);
470                debug_assert!(!ptr.is_null());
471                from_glib_full(ptr as *mut $ffi_type)
472            }
473        }
474
475        #[doc(hidden)]
476        unsafe impl<'a> crate::value::FromValue<'a> for &'a $rust_type {
477            type Checker = crate::value::GenericValueTypeOrNoneChecker<Self>;
478
479            unsafe fn from_value(value: &'a crate::Value) -> Self {
480                debug_assert_eq!(std::mem::size_of::<Self>(), std::mem::size_of::<crate::ffi::gpointer>());
481                let value = &*(value as *const crate::Value as *const crate::gobject_ffi::GValue);
482                let ptr = &value.data[0].v_pointer as *const crate::ffi::gpointer as *const *const gobject_ffi::GParamSpec;
483                debug_assert!(!(*ptr).is_null());
484                &*(ptr as *const $rust_type)
485            }
486        }
487
488        #[doc(hidden)]
489        impl crate::value::ToValue for $rust_type {
490            fn to_value(&self) -> crate::Value {
491                unsafe {
492                    let mut value = crate::Value::from_type_unchecked($rust_type::static_type());
493                    gobject_ffi::g_value_take_param(value.to_glib_none_mut().0, $crate::translate::ToGlibPtr::<*const $ffi_type>::to_glib_full(self) as *mut _);
494                    value
495                }
496            }
497
498            fn value_type(&self) -> crate::Type {
499                $rust_type::static_type()
500            }
501        }
502
503        #[doc(hidden)]
504        impl From<$rust_type> for crate::Value {
505            #[inline]
506            fn from(s: $rust_type) -> Self {
507                unsafe {
508                    let mut value = crate::Value::from_type_unchecked($rust_type::static_type());
509                    gobject_ffi::g_value_take_param(
510                        value.to_glib_none_mut().0,
511                        $crate::translate::IntoGlibPtr::<*mut gobject_ffi::GParamSpec>::into_glib_ptr(s),
512                    );
513                    value
514                }
515            }
516        }
517
518        #[doc(hidden)]
519        impl crate::value::ToValueOptional for $rust_type {
520            fn to_value_optional(s: Option<&Self>) -> crate::Value {
521                let mut value = crate::Value::for_value_type::<Self>();
522                unsafe {
523                    gobject_ffi::g_value_take_param(value.to_glib_none_mut().0, $crate::translate::ToGlibPtr::<*const $ffi_type>::to_glib_full(&s) as *mut _);
524                }
525
526                value
527            }
528        }
529
530        unsafe impl Send for $rust_type {}
531        unsafe impl Sync for $rust_type {}
532
533        impl std::ops::Deref for $rust_type {
534            type Target = ParamSpec;
535
536            #[inline]
537            fn deref(&self) -> &Self::Target {
538                unsafe {
539                    &*(self as *const $rust_type as *const ParamSpec)
540                }
541            }
542        }
543
544        unsafe impl ParamSpecType for $rust_type {}
545
546        #[doc(hidden)]
547        impl<'a> ToGlibPtr<'a, *const gobject_ffi::GParamSpec> for $rust_type {
548            type Storage = std::marker::PhantomData<&'a $crate::shared::Shared<$ffi_type, $rust_type>>;
549
550            #[inline]
551            fn to_glib_none(&'a self) -> $crate::translate::Stash<'a, *const gobject_ffi::GParamSpec, Self> {
552                let stash = $crate::translate::ToGlibPtr::<*const $ffi_type>::to_glib_none(self);
553                $crate::translate::Stash(stash.0 as *const _, stash.1)
554            }
555
556            #[inline]
557            fn to_glib_full(&self) -> *const gobject_ffi::GParamSpec {
558                $crate::translate::ToGlibPtr::<*const $ffi_type>::to_glib_full(self) as *const _
559            }
560        }
561
562        #[doc(hidden)]
563        impl<'a> ToGlibPtr<'a, *mut gobject_ffi::GParamSpec> for $rust_type {
564            type Storage = std::marker::PhantomData<&'a $crate::shared::Shared<$ffi_type, $rust_type>>;
565
566            #[inline]
567            fn to_glib_none(&'a self) -> $crate::translate::Stash<'a, *mut gobject_ffi::GParamSpec, Self> {
568                let stash = $crate::translate::ToGlibPtr::<*mut $ffi_type>::to_glib_none(self);
569                $crate::translate::Stash(stash.0 as *mut _, stash.1)
570            }
571
572            #[inline]
573            fn to_glib_full(&self) -> *mut gobject_ffi::GParamSpec {
574                $crate::translate::ToGlibPtr::<*mut $ffi_type>::to_glib_full(self) as *mut _
575            }
576        }
577
578        #[doc(hidden)]
579        impl IntoGlibPtr<*mut gobject_ffi::GParamSpec> for $rust_type {
580            #[inline]
581            unsafe fn into_glib_ptr(self) -> *mut gobject_ffi::GParamSpec {
582                let s = std::mem::ManuallyDrop::new(self);
583                s.to_glib_none().0
584            }
585        }
586
587        #[doc(hidden)]
588        impl IntoGlibPtr<*const gobject_ffi::GParamSpec> for $rust_type {
589            #[inline]
590            unsafe fn into_glib_ptr(self) -> *const gobject_ffi::GParamSpec {
591                let s = std::mem::ManuallyDrop::new(self);
592                s.to_glib_none().0
593            }
594        }
595
596        #[doc(hidden)]
597        impl FromGlibPtrNone<*const gobject_ffi::GParamSpec> for $rust_type {
598            #[inline]
599            unsafe fn from_glib_none(ptr: *const gobject_ffi::GParamSpec) -> Self {
600                from_glib_none(ptr as *const $ffi_type)
601            }
602        }
603
604        #[doc(hidden)]
605        impl FromGlibPtrNone<*mut gobject_ffi::GParamSpec> for $rust_type {
606            #[inline]
607            unsafe fn from_glib_none(ptr: *mut gobject_ffi::GParamSpec) -> Self {
608                from_glib_none(ptr as *mut $ffi_type)
609            }
610        }
611
612        #[doc(hidden)]
613        impl FromGlibPtrBorrow<*const gobject_ffi::GParamSpec> for $rust_type {
614            #[inline]
615            unsafe fn from_glib_borrow(ptr: *const gobject_ffi::GParamSpec) -> Borrowed<Self> {
616                from_glib_borrow(ptr as *const $ffi_type)
617            }
618        }
619
620        #[doc(hidden)]
621        impl FromGlibPtrBorrow<*mut gobject_ffi::GParamSpec> for $rust_type {
622            #[inline]
623            unsafe fn from_glib_borrow(ptr: *mut gobject_ffi::GParamSpec) -> Borrowed<Self> {
624                from_glib_borrow(ptr as *mut $ffi_type)
625            }
626        }
627
628        #[doc(hidden)]
629        impl FromGlibPtrFull<*mut gobject_ffi::GParamSpec> for $rust_type {
630            #[inline]
631            unsafe fn from_glib_full(ptr: *mut gobject_ffi::GParamSpec) -> Self {
632                from_glib_full(ptr as *mut $ffi_type)
633            }
634        }
635
636        impl $rust_type {
637            #[inline]
638            pub fn upcast(self) -> ParamSpec {
639                unsafe {
640                    from_glib_full(IntoGlibPtr::<*mut $ffi_type>::into_glib_ptr(self) as *mut gobject_ffi::GParamSpec)
641                }
642            }
643
644            #[inline]
645            pub fn upcast_ref(&self) -> &ParamSpec {
646                &*self
647            }
648        }
649
650        impl AsRef<ParamSpec> for $rust_type {
651            #[inline]
652            fn as_ref(&self) -> &ParamSpec {
653                &self
654            }
655        }
656    };
657}
658
659macro_rules! define_param_spec_default {
660    ($rust_type:ident, $ffi_type:path, $value_type:ty, $from_glib:expr) => {
661        impl $rust_type {
662            #[inline]
663            #[allow(clippy::redundant_closure_call)]
664            pub fn default_value(&self) -> $value_type {
665                unsafe {
666                    let ptr =
667                        $crate::translate::ToGlibPtr::<*const $ffi_type>::to_glib_none(self).0;
668                    $from_glib((*ptr).default_value)
669                }
670            }
671        }
672    };
673}
674
675macro_rules! define_param_spec_min_max {
676    ($rust_type:ident, $ffi_type:path, $value_type:ty) => {
677        impl $rust_type {
678            #[inline]
679            pub fn minimum(&self) -> $value_type {
680                unsafe {
681                    let ptr =
682                        $crate::translate::ToGlibPtr::<*const $ffi_type>::to_glib_none(self).0;
683                    (*ptr).minimum
684                }
685            }
686
687            #[inline]
688            pub fn maximum(&self) -> $value_type {
689                unsafe {
690                    let ptr =
691                        $crate::translate::ToGlibPtr::<*const $ffi_type>::to_glib_none(self).0;
692                    (*ptr).maximum
693                }
694            }
695        }
696    };
697}
698
699macro_rules! define_param_spec_numeric {
700    ($rust_type:ident, $ffi_type:path, $value_type:ty, $type_name:literal, $ffi_fun:ident) => {
701        define_param_spec!($rust_type, $ffi_type, $type_name);
702        define_param_spec_default!($rust_type, $ffi_type, $value_type, |x| x);
703        define_param_spec_min_max!($rust_type, $ffi_type, $value_type);
704
705        impl $rust_type {
706            unsafe fn new_unchecked<'a>(
707                name: &str,
708                nick: impl Into<Option<&'a str>>,
709                blurb: impl Into<Option<&'a str>>,
710                minimum: $value_type,
711                maximum: $value_type,
712                default_value: $value_type,
713                flags: ParamFlags,
714            ) -> ParamSpec {
715                unsafe {
716                    from_glib_none(gobject_ffi::$ffi_fun(
717                        name.to_glib_none().0,
718                        nick.into().to_glib_none().0,
719                        blurb.into().to_glib_none().0,
720                        minimum,
721                        maximum,
722                        default_value,
723                        flags.into_glib(),
724                    ))
725                }
726            }
727        }
728    };
729}
730
731/// A trait implemented by the various [`ParamSpec`] builder types.
732///
733/// It is useful for providing a builder pattern for [`ParamSpec`] defined
734/// outside of GLib like in GStreamer or GTK 4.
735pub trait ParamSpecBuilderExt<'a>: Sized {
736    /// Implementation detail.
737    fn set_nick(&mut self, nick: Option<&'a str>);
738    /// Implementation detail.
739    fn set_blurb(&mut self, blurb: Option<&'a str>);
740    /// Implementation detail.
741    fn set_flags(&mut self, flags: crate::ParamFlags);
742    /// Implementation detail.
743    fn current_flags(&self) -> crate::ParamFlags;
744
745    /// By default, the nickname of its redirect target will be used if it has one.
746    /// Otherwise, `self.name` will be used.
747    fn nick(mut self, nick: &'a str) -> Self {
748        self.set_nick(Some(nick));
749        self
750    }
751
752    /// Default: `None`
753    fn blurb(mut self, blurb: &'a str) -> Self {
754        self.set_blurb(Some(blurb));
755        self
756    }
757
758    /// Default: `glib::ParamFlags::READWRITE`
759    fn flags(mut self, flags: crate::ParamFlags) -> Self {
760        self.set_flags(flags);
761        self
762    }
763
764    /// Mark the property as read only and drops the READWRITE flag set by default.
765    fn read_only(self) -> Self {
766        let flags =
767            (self.current_flags() - crate::ParamFlags::WRITABLE) | crate::ParamFlags::READABLE;
768        self.flags(flags)
769    }
770
771    /// Mark the property as write only and drops the READWRITE flag set by default.
772    fn write_only(self) -> Self {
773        let flags =
774            (self.current_flags() - crate::ParamFlags::READABLE) | crate::ParamFlags::WRITABLE;
775        self.flags(flags)
776    }
777
778    /// Mark the property as readwrite, it is the default value.
779    fn readwrite(self) -> Self {
780        let flags = self.current_flags() | crate::ParamFlags::READWRITE;
781        self.flags(flags)
782    }
783
784    /// Mark the property as construct
785    fn construct(self) -> Self {
786        let flags = self.current_flags() | crate::ParamFlags::CONSTRUCT;
787        self.flags(flags)
788    }
789
790    /// Mark the property as construct only
791    fn construct_only(self) -> Self {
792        let flags = self.current_flags() | crate::ParamFlags::CONSTRUCT_ONLY;
793        self.flags(flags)
794    }
795
796    /// Mark the property as lax validation
797    fn lax_validation(self) -> Self {
798        let flags = self.current_flags() | crate::ParamFlags::LAX_VALIDATION;
799        self.flags(flags)
800    }
801
802    /// Mark the property as explicit notify
803    fn explicit_notify(self) -> Self {
804        let flags = self.current_flags() | crate::ParamFlags::EXPLICIT_NOTIFY;
805        self.flags(flags)
806    }
807
808    /// Mark the property as deprecated
809    fn deprecated(self) -> Self {
810        let flags = self.current_flags() | crate::ParamFlags::DEPRECATED;
811        self.flags(flags)
812    }
813}
814
815macro_rules! define_builder {
816    (@constructors $rust_type:ident, $alias:literal, $builder_type:ident $(($($req_ident:ident: $req_ty:ty,)*))?) => {
817        impl<'a> $builder_type<'a> {
818            fn new(name: &'a str, $($($req_ident: $req_ty)*)?) -> Self {
819                assert_param_name(name);
820                Self {
821                    name,
822                    $($($req_ident: Some($req_ident),)*)?
823                    ..Default::default()
824                }
825            }
826        }
827
828        impl $rust_type {
829            #[doc(alias = $alias)]
830            pub fn builder(name: &str, $($($req_ident: $req_ty),*)?) -> $builder_type<'_> {
831                $builder_type::new(name, $($($req_ident),*)?)
832            }
833        }
834
835        impl<'a> crate::prelude::ParamSpecBuilderExt<'a> for $builder_type<'a> {
836            fn set_nick(&mut self, nick: Option<&'a str>) {
837                self.nick = nick;
838            }
839            fn set_blurb(&mut self, blurb: Option<&'a str>) {
840                self.blurb = blurb;
841            }
842            fn set_flags(&mut self, flags: crate::ParamFlags) {
843                self.flags = flags;
844            }
845            fn current_flags(&self) -> crate::ParamFlags {
846                self.flags
847            }
848        }
849    };
850    (
851        $rust_type:ident, $alias:literal, $builder_type:ident {
852            $($field_id:ident: $field_ty:ty $(= $field_expr:expr)?,)*
853        }
854        $(requires $required_tt:tt)?
855    ) => {
856        #[derive(Default)]
857        #[must_use]
858        pub struct $builder_type<'a> {
859            name: &'a str,
860            nick: Option<&'a str>,
861            blurb: Option<&'a str>,
862            flags: crate::ParamFlags,
863            $($field_id: Option<$field_ty>),*
864        }
865        impl<'a> $builder_type<'a> {
866            $(
867            $(#[doc = concat!("Default: `", stringify!($field_expr), "`")])?
868            pub fn $field_id(mut self, value: $field_ty) -> Self {
869                self.$field_id = Some(value);
870                self
871            }
872            )*
873
874            #[must_use]
875            pub fn build(self) -> ParamSpec {
876                unsafe {
877                    $rust_type::new_unchecked(
878                        self.name,
879                        self.nick,
880                        self.blurb,
881                        $(self
882                            .$field_id
883                            $(.or(Some($field_expr)))?
884                            .expect("impossible: missing parameter in ParamSpec*Builder")
885                        ,)*
886                        self.flags
887                    )
888                }
889            }
890        }
891        define_builder!(@constructors $rust_type, $alias, $builder_type $($required_tt)?);
892    }
893}
894macro_rules! define_builder_numeric {
895    ($rust_type:ident, $alias:literal, $builder_type:ident, $n_ty:ty) => {
896        define_builder!(
897            $rust_type,
898            $alias,
899            $builder_type {
900                minimum: $n_ty = <$n_ty>::MIN,
901                maximum: $n_ty = <$n_ty>::MAX,
902                default_value: $n_ty = <$n_ty as Default>::default(),
903            }
904        );
905    };
906}
907
908#[track_caller]
909// the default panic formatter will use its caller as the location in its error message
910fn assert_param_name(name: &str) {
911    assert!(
912        is_canonical_pspec_name(name),
913        "{name} is not a valid canonical parameter name",
914    );
915}
916
917wrapper! {
918    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
919    #[doc(alias = "GParamSpecChar")]
920    pub struct ParamSpecChar(Shared<gobject_ffi::GParamSpecChar>);
921
922    match fn {
923        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut gobject_ffi::GParamSpecChar,
924        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
925    }
926}
927define_param_spec_numeric!(
928    ParamSpecChar,
929    gobject_ffi::GParamSpecChar,
930    i8,
931    "GParamChar",
932    g_param_spec_char
933);
934
935define_builder_numeric!(ParamSpecChar, "g_param_spec_char", ParamSpecCharBuilder, i8);
936
937wrapper! {
938    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
939    #[doc(alias = "GParamSpecUChar")]
940    pub struct ParamSpecUChar(Shared<gobject_ffi::GParamSpecUChar>);
941
942    match fn {
943        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut gobject_ffi::GParamSpecUChar,
944        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
945    }
946}
947define_param_spec_numeric!(
948    ParamSpecUChar,
949    gobject_ffi::GParamSpecUChar,
950    u8,
951    "GParamUChar",
952    g_param_spec_uchar
953);
954
955define_builder_numeric!(
956    ParamSpecUChar,
957    "g_param_spec_uchar",
958    ParamSpecUCharBuilder,
959    u8
960);
961
962wrapper! {
963    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
964    #[doc(alias = "GParamSpecBoolean")]
965    pub struct ParamSpecBoolean(Shared<gobject_ffi::GParamSpecBoolean>);
966
967    match fn {
968        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut gobject_ffi::GParamSpecBoolean,
969        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
970    }
971}
972define_param_spec!(
973    ParamSpecBoolean,
974    gobject_ffi::GParamSpecBoolean,
975    "GParamBoolean"
976);
977
978define_param_spec_default!(
979    ParamSpecBoolean,
980    gobject_ffi::GParamSpecBoolean,
981    bool,
982    |x| from_glib(x)
983);
984
985impl ParamSpecBoolean {
986    unsafe fn new_unchecked<'a>(
987        name: &str,
988        nick: impl Into<Option<&'a str>>,
989        blurb: impl Into<Option<&'a str>>,
990        default_value: bool,
991        flags: ParamFlags,
992    ) -> ParamSpec {
993        unsafe {
994            from_glib_none(gobject_ffi::g_param_spec_boolean(
995                name.to_glib_none().0,
996                nick.into().to_glib_none().0,
997                blurb.into().to_glib_none().0,
998                default_value.into_glib(),
999                flags.into_glib(),
1000            ))
1001        }
1002    }
1003}
1004
1005define_builder!(
1006    ParamSpecBoolean,
1007    "g_param_spec_builder",
1008    ParamSpecBooleanBuilder {
1009        default_value: bool = false,
1010    }
1011);
1012
1013wrapper! {
1014    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1015    #[doc(alias = "GParamSpecInt")]
1016    pub struct ParamSpecInt(Shared<gobject_ffi::GParamSpecInt>);
1017
1018    match fn {
1019        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut gobject_ffi::GParamSpecInt,
1020        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
1021    }
1022}
1023define_param_spec_numeric!(
1024    ParamSpecInt,
1025    gobject_ffi::GParamSpecInt,
1026    i32,
1027    "GParamInt",
1028    g_param_spec_int
1029);
1030
1031define_builder_numeric!(ParamSpecInt, "g_param_spec_int", ParamSpecIntBuilder, i32);
1032
1033wrapper! {
1034    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1035    #[doc(alias = "GParamSpecUInt")]
1036    pub struct ParamSpecUInt(Shared<gobject_ffi::GParamSpecUInt>);
1037
1038    match fn {
1039        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut gobject_ffi::GParamSpecUInt,
1040        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
1041    }
1042}
1043define_param_spec_numeric!(
1044    ParamSpecUInt,
1045    gobject_ffi::GParamSpecUInt,
1046    u32,
1047    "GParamUInt",
1048    g_param_spec_uint
1049);
1050
1051define_builder_numeric!(
1052    ParamSpecUInt,
1053    "g_param_spec_uint",
1054    ParamSpecUIntBuilder,
1055    u32
1056);
1057
1058wrapper! {
1059    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1060    #[doc(alias = "GParamSpecLong")]
1061    pub struct ParamSpecLong(Shared<gobject_ffi::GParamSpecLong>);
1062
1063    match fn {
1064        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut gobject_ffi::GParamSpecLong,
1065        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
1066    }
1067}
1068define_param_spec_numeric!(
1069    ParamSpecLong,
1070    gobject_ffi::GParamSpecLong,
1071    libc::c_long,
1072    "GParamLong",
1073    g_param_spec_long
1074);
1075
1076define_builder_numeric!(
1077    ParamSpecLong,
1078    "g_param_spec_long",
1079    ParamSpecLongBuilder,
1080    libc::c_long
1081);
1082
1083wrapper! {
1084    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1085    #[doc(alias = "GParamSpecULong")]
1086    pub struct ParamSpecULong(Shared<gobject_ffi::GParamSpecULong>);
1087
1088    match fn {
1089        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut gobject_ffi::GParamSpecULong,
1090        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
1091    }
1092}
1093define_param_spec_numeric!(
1094    ParamSpecULong,
1095    gobject_ffi::GParamSpecULong,
1096    libc::c_ulong,
1097    "GParamULong",
1098    g_param_spec_ulong
1099);
1100
1101define_builder_numeric!(
1102    ParamSpecULong,
1103    "g_param_spec_ulong",
1104    ParamSpecULongBuilder,
1105    libc::c_ulong
1106);
1107
1108wrapper! {
1109    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1110    #[doc(alias = "GParamSpecInt64")]
1111    pub struct ParamSpecInt64(Shared<gobject_ffi::GParamSpecInt64>);
1112
1113    match fn {
1114        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut gobject_ffi::GParamSpecInt64,
1115        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
1116    }
1117}
1118define_param_spec_numeric!(
1119    ParamSpecInt64,
1120    gobject_ffi::GParamSpecInt64,
1121    i64,
1122    "GParamInt64",
1123    g_param_spec_int64
1124);
1125
1126define_builder_numeric!(
1127    ParamSpecInt64,
1128    "g_param_spec_int64",
1129    ParamSpecInt64Builder,
1130    i64
1131);
1132
1133wrapper! {
1134    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1135    #[doc(alias = "GParamSpecUInt64")]
1136    pub struct ParamSpecUInt64(Shared<gobject_ffi::GParamSpecUInt64>);
1137
1138    match fn {
1139        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut gobject_ffi::GParamSpecUInt64,
1140        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
1141    }
1142}
1143define_param_spec_numeric!(
1144    ParamSpecUInt64,
1145    gobject_ffi::GParamSpecUInt64,
1146    u64,
1147    "GParamUInt64",
1148    g_param_spec_uint64
1149);
1150
1151define_builder_numeric!(
1152    ParamSpecUInt64,
1153    "g_param_spec_uint64",
1154    ParamSpecUInt64Builder,
1155    u64
1156);
1157
1158wrapper! {
1159    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1160    #[doc(alias = "GParamSpecUnichar")]
1161    pub struct ParamSpecUnichar(Shared<gobject_ffi::GParamSpecUnichar>);
1162
1163    match fn {
1164        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut gobject_ffi::GParamSpecUnichar,
1165        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
1166    }
1167}
1168define_param_spec!(
1169    ParamSpecUnichar,
1170    gobject_ffi::GParamSpecUnichar,
1171    "GParamUnichar"
1172);
1173define_param_spec_default!(ParamSpecUnichar, gobject_ffi::GParamSpecUnichar, Result<char, CharTryFromError>, TryFrom::try_from);
1174
1175impl ParamSpecUnichar {
1176    unsafe fn new_unchecked<'a>(
1177        name: &str,
1178        nick: impl Into<Option<&'a str>>,
1179        blurb: impl Into<Option<&'a str>>,
1180        default_value: char,
1181        flags: ParamFlags,
1182    ) -> ParamSpec {
1183        unsafe {
1184            from_glib_none(gobject_ffi::g_param_spec_unichar(
1185                name.to_glib_none().0,
1186                nick.into().to_glib_none().0,
1187                blurb.into().to_glib_none().0,
1188                default_value.into_glib(),
1189                flags.into_glib(),
1190            ))
1191        }
1192    }
1193}
1194
1195define_builder!(
1196    ParamSpecUnichar,
1197    "g_param_spec_unichar",
1198    ParamSpecUnicharBuilder {
1199        default_value: char,
1200    }
1201    requires (default_value: char,)
1202);
1203
1204wrapper! {
1205    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1206    #[doc(alias = "GParamSpecEnum")]
1207    pub struct ParamSpecEnum(Shared<gobject_ffi::GParamSpecEnum>);
1208
1209    match fn {
1210        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut gobject_ffi::GParamSpecEnum,
1211        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
1212    }
1213}
1214define_param_spec!(ParamSpecEnum, gobject_ffi::GParamSpecEnum, "GParamEnum");
1215
1216impl ParamSpecEnum {
1217    unsafe fn new_unchecked<'a>(
1218        name: &str,
1219        nick: impl Into<Option<&'a str>>,
1220        blurb: impl Into<Option<&'a str>>,
1221        enum_type: crate::Type,
1222        default_value: i32,
1223        flags: ParamFlags,
1224    ) -> ParamSpec {
1225        unsafe {
1226            from_glib_none(gobject_ffi::g_param_spec_enum(
1227                name.to_glib_none().0,
1228                nick.into().to_glib_none().0,
1229                blurb.into().to_glib_none().0,
1230                enum_type.into_glib(),
1231                default_value,
1232                flags.into_glib(),
1233            ))
1234        }
1235    }
1236
1237    #[doc(alias = "get_enum_class")]
1238    #[inline]
1239    pub fn enum_class(&self) -> crate::EnumClass {
1240        unsafe {
1241            let ptr = ToGlibPtr::<*const gobject_ffi::GParamSpecEnum>::to_glib_none(self).0;
1242
1243            debug_assert!(!(*ptr).enum_class.is_null());
1244
1245            crate::EnumClass::with_type(from_glib((*(*ptr).enum_class).g_type_class.g_type))
1246                .expect("Invalid enum class")
1247        }
1248    }
1249
1250    #[inline]
1251    pub fn default_value<T: StaticType + FromGlib<i32>>(&self) -> Result<T, crate::BoolError> {
1252        unsafe {
1253            if !self.enum_class().type_().is_a(T::static_type()) {
1254                return Err(bool_error!(
1255                    "Wrong type -- expected {} got {}",
1256                    self.enum_class().type_(),
1257                    T::static_type()
1258                ));
1259            }
1260            Ok(from_glib(self.default_value_as_i32()))
1261        }
1262    }
1263
1264    #[inline]
1265    pub fn default_value_as_i32(&self) -> i32 {
1266        unsafe {
1267            let ptr = ToGlibPtr::<*const gobject_ffi::GParamSpecEnum>::to_glib_none(self).0;
1268            (*ptr).default_value
1269        }
1270    }
1271
1272    #[doc(alias = "g_param_spec_enum")]
1273    pub fn builder_with_default<T: StaticType + FromGlib<i32> + IntoGlib<GlibType = i32>>(
1274        name: &str,
1275        default_value: T,
1276    ) -> ParamSpecEnumBuilder<T> {
1277        ParamSpecEnumBuilder::new(name, default_value)
1278    }
1279
1280    #[doc(alias = "g_param_spec_enum")]
1281    pub fn builder<T: StaticType + FromGlib<i32> + IntoGlib<GlibType = i32> + Default>(
1282        name: &str,
1283    ) -> ParamSpecEnumBuilder<T> {
1284        ParamSpecEnumBuilder::new(name, T::default())
1285    }
1286}
1287
1288#[must_use]
1289pub struct ParamSpecEnumBuilder<'a, T: StaticType + FromGlib<i32> + IntoGlib<GlibType = i32>> {
1290    name: &'a str,
1291    nick: Option<&'a str>,
1292    blurb: Option<&'a str>,
1293    flags: crate::ParamFlags,
1294    default_value: T,
1295}
1296
1297impl<'a, T: StaticType + FromGlib<i32> + IntoGlib<GlibType = i32>> ParamSpecEnumBuilder<'a, T> {
1298    fn new(name: &'a str, default_value: T) -> Self {
1299        assert_param_name(name);
1300        assert!(T::static_type().is_a(Type::ENUM));
1301
1302        Self {
1303            name,
1304            nick: None,
1305            blurb: None,
1306            flags: crate::ParamFlags::default(),
1307            default_value,
1308        }
1309    }
1310
1311    pub fn default_value(mut self, default: T) -> Self {
1312        self.default_value = default;
1313        self
1314    }
1315
1316    #[must_use]
1317    pub fn build(self) -> ParamSpec {
1318        unsafe {
1319            ParamSpecEnum::new_unchecked(
1320                self.name,
1321                self.nick,
1322                self.blurb,
1323                T::static_type(),
1324                self.default_value.into_glib(),
1325                self.flags,
1326            )
1327        }
1328    }
1329}
1330
1331impl<'a, T: StaticType + FromGlib<i32> + IntoGlib<GlibType = i32>>
1332    crate::prelude::ParamSpecBuilderExt<'a> for ParamSpecEnumBuilder<'a, T>
1333{
1334    fn set_nick(&mut self, nick: Option<&'a str>) {
1335        self.nick = nick;
1336    }
1337    fn set_blurb(&mut self, blurb: Option<&'a str>) {
1338        self.blurb = blurb;
1339    }
1340    fn set_flags(&mut self, flags: crate::ParamFlags) {
1341        self.flags = flags;
1342    }
1343    fn current_flags(&self) -> crate::ParamFlags {
1344        self.flags
1345    }
1346}
1347
1348wrapper! {
1349    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1350    #[doc(alias = "GParamSpecFlags")]
1351    pub struct ParamSpecFlags(Shared<gobject_ffi::GParamSpecFlags>);
1352
1353    match fn {
1354        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut gobject_ffi::GParamSpecFlags,
1355        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
1356    }
1357}
1358define_param_spec!(ParamSpecFlags, gobject_ffi::GParamSpecFlags, "GParamFlags");
1359
1360impl ParamSpecFlags {
1361    unsafe fn new_unchecked<'a>(
1362        name: &str,
1363        nick: impl Into<Option<&'a str>>,
1364        blurb: impl Into<Option<&'a str>>,
1365        flags_type: crate::Type,
1366        default_value: u32,
1367        flags: ParamFlags,
1368    ) -> ParamSpec {
1369        unsafe {
1370            from_glib_none(gobject_ffi::g_param_spec_flags(
1371                name.to_glib_none().0,
1372                nick.into().to_glib_none().0,
1373                blurb.into().to_glib_none().0,
1374                flags_type.into_glib(),
1375                default_value,
1376                flags.into_glib(),
1377            ))
1378        }
1379    }
1380
1381    #[doc(alias = "get_flags_class")]
1382    #[inline]
1383    pub fn flags_class(&self) -> crate::FlagsClass {
1384        unsafe {
1385            let ptr = ToGlibPtr::<*const gobject_ffi::GParamSpecFlags>::to_glib_none(self).0;
1386
1387            debug_assert!(!(*ptr).flags_class.is_null());
1388
1389            crate::FlagsClass::with_type(from_glib((*(*ptr).flags_class).g_type_class.g_type))
1390                .expect("Invalid flags class")
1391        }
1392    }
1393
1394    #[inline]
1395    pub fn default_value<T: StaticType + FromGlib<u32>>(&self) -> Result<T, crate::BoolError> {
1396        unsafe {
1397            if !self.flags_class().type_().is_a(T::static_type()) {
1398                return Err(bool_error!(
1399                    "Wrong type -- expected {} got {}",
1400                    self.flags_class().type_(),
1401                    T::static_type()
1402                ));
1403            }
1404            Ok(from_glib(self.default_value_as_u32()))
1405        }
1406    }
1407
1408    #[inline]
1409    pub fn default_value_as_u32(&self) -> u32 {
1410        unsafe {
1411            let ptr = ToGlibPtr::<*const gobject_ffi::GParamSpecFlags>::to_glib_none(self).0;
1412            (*ptr).default_value
1413        }
1414    }
1415
1416    #[doc(alias = "g_param_spec_flags")]
1417    pub fn builder<T: StaticType + FromGlib<u32> + IntoGlib<GlibType = u32>>(
1418        name: &str,
1419    ) -> ParamSpecFlagsBuilder<T> {
1420        ParamSpecFlagsBuilder::new(name)
1421    }
1422}
1423
1424#[must_use]
1425pub struct ParamSpecFlagsBuilder<'a, T: StaticType + FromGlib<u32> + IntoGlib<GlibType = u32>> {
1426    name: &'a str,
1427    nick: Option<&'a str>,
1428    blurb: Option<&'a str>,
1429    flags: crate::ParamFlags,
1430    default_value: T,
1431}
1432
1433impl<'a, T: StaticType + FromGlib<u32> + IntoGlib<GlibType = u32>> ParamSpecFlagsBuilder<'a, T> {
1434    fn new(name: &'a str) -> Self {
1435        assert_param_name(name);
1436        assert!(T::static_type().is_a(Type::FLAGS));
1437
1438        unsafe {
1439            Self {
1440                name,
1441                nick: None,
1442                blurb: None,
1443                flags: crate::ParamFlags::default(),
1444                default_value: from_glib(0),
1445            }
1446        }
1447    }
1448
1449    #[doc = "Default: 0`"]
1450    pub fn default_value(mut self, value: T) -> Self {
1451        self.default_value = value;
1452        self
1453    }
1454
1455    #[must_use]
1456    pub fn build(self) -> ParamSpec {
1457        unsafe {
1458            ParamSpecFlags::new_unchecked(
1459                self.name,
1460                self.nick,
1461                self.blurb,
1462                T::static_type(),
1463                self.default_value.into_glib(),
1464                self.flags,
1465            )
1466        }
1467    }
1468}
1469
1470impl<'a, T: StaticType + FromGlib<u32> + IntoGlib<GlibType = u32>>
1471    crate::prelude::ParamSpecBuilderExt<'a> for ParamSpecFlagsBuilder<'a, T>
1472{
1473    fn set_nick(&mut self, nick: Option<&'a str>) {
1474        self.nick = nick;
1475    }
1476    fn set_blurb(&mut self, blurb: Option<&'a str>) {
1477        self.blurb = blurb;
1478    }
1479    fn set_flags(&mut self, flags: crate::ParamFlags) {
1480        self.flags = flags;
1481    }
1482    fn current_flags(&self) -> crate::ParamFlags {
1483        self.flags
1484    }
1485}
1486
1487wrapper! {
1488    /// A [`ParamSpec`][crate::ParamSpec] derived structure that contains the meta data for float properties.
1489    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1490    #[doc(alias = "GParamSpecFloat")]
1491    pub struct ParamSpecFloat(Shared<gobject_ffi::GParamSpecFloat>);
1492
1493    match fn {
1494        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut gobject_ffi::GParamSpecFloat,
1495        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
1496    }
1497}
1498define_param_spec_numeric!(
1499    ParamSpecFloat,
1500    gobject_ffi::GParamSpecFloat,
1501    f32,
1502    "GParamFloat",
1503    g_param_spec_float
1504);
1505
1506define_builder_numeric!(
1507    ParamSpecFloat,
1508    "g_param_spec_float",
1509    ParamSpecFloatBuilder,
1510    f32
1511);
1512
1513wrapper! {
1514    /// A [`ParamSpec`][crate::ParamSpec] derived structure that contains the meta data for double properties.
1515    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1516    #[doc(alias = "GParamSpecDouble")]
1517    pub struct ParamSpecDouble(Shared<gobject_ffi::GParamSpecDouble>);
1518
1519    match fn {
1520        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut gobject_ffi::GParamSpecDouble,
1521        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
1522    }
1523}
1524define_param_spec_numeric!(
1525    ParamSpecDouble,
1526    gobject_ffi::GParamSpecDouble,
1527    f64,
1528    "GParamDouble",
1529    g_param_spec_double
1530);
1531
1532define_builder_numeric!(
1533    ParamSpecDouble,
1534    "g_param_spec_double",
1535    ParamSpecDoubleBuilder,
1536    f64
1537);
1538
1539wrapper! {
1540    /// A [`ParamSpec`][crate::ParamSpec] derived structure that contains the meta data for string
1541    /// properties.
1542    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1543    #[doc(alias = "GParamSpecString")]
1544    pub struct ParamSpecString(Shared<gobject_ffi::GParamSpecString>);
1545
1546    match fn {
1547        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut gobject_ffi::GParamSpecString,
1548        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
1549    }
1550}
1551define_param_spec!(
1552    ParamSpecString,
1553    gobject_ffi::GParamSpecString,
1554    "GParamString"
1555);
1556
1557define_param_spec_default!(
1558    ParamSpecString,
1559    gobject_ffi::GParamSpecString,
1560    Option<&str>,
1561    |x: *mut libc::c_char| {
1562        use std::ffi::CStr;
1563
1564        if x.is_null() {
1565            None
1566        } else {
1567            Some(CStr::from_ptr(x).to_str().unwrap())
1568        }
1569    }
1570);
1571
1572impl ParamSpecString {
1573    unsafe fn new_unchecked<'a>(
1574        name: &str,
1575        nick: impl Into<Option<&'a str>>,
1576        blurb: impl Into<Option<&'a str>>,
1577        default_value: Option<&str>,
1578        flags: ParamFlags,
1579    ) -> ParamSpec {
1580        let default_value = default_value.to_glib_none();
1581        unsafe {
1582            from_glib_none(gobject_ffi::g_param_spec_string(
1583                name.to_glib_none().0,
1584                nick.into().to_glib_none().0,
1585                blurb.into().to_glib_none().0,
1586                default_value.0,
1587                flags.into_glib(),
1588            ))
1589        }
1590    }
1591
1592    #[doc(alias = "g_param_spec_string")]
1593    pub fn builder(name: &str) -> ParamSpecStringBuilder {
1594        ParamSpecStringBuilder::new(name)
1595    }
1596}
1597
1598#[must_use]
1599pub struct ParamSpecStringBuilder<'a> {
1600    name: &'a str,
1601    nick: Option<&'a str>,
1602    blurb: Option<&'a str>,
1603    flags: crate::ParamFlags,
1604    default_value: Option<&'a str>,
1605}
1606
1607impl<'a> ParamSpecStringBuilder<'a> {
1608    fn new(name: &'a str) -> Self {
1609        assert_param_name(name);
1610        Self {
1611            name,
1612            nick: None,
1613            blurb: None,
1614            flags: crate::ParamFlags::default(),
1615            default_value: None,
1616        }
1617    }
1618
1619    #[doc = "Default: None`"]
1620    pub fn default_value(mut self, value: impl Into<Option<&'a str>>) -> Self {
1621        self.default_value = value.into();
1622        self
1623    }
1624
1625    #[must_use]
1626    pub fn build(self) -> ParamSpec {
1627        unsafe {
1628            ParamSpecString::new_unchecked(
1629                self.name,
1630                self.nick,
1631                self.blurb,
1632                self.default_value,
1633                self.flags,
1634            )
1635        }
1636    }
1637}
1638
1639impl<'a> crate::prelude::ParamSpecBuilderExt<'a> for ParamSpecStringBuilder<'a> {
1640    fn set_nick(&mut self, nick: Option<&'a str>) {
1641        self.nick = nick;
1642    }
1643    fn set_blurb(&mut self, blurb: Option<&'a str>) {
1644        self.blurb = blurb;
1645    }
1646    fn set_flags(&mut self, flags: crate::ParamFlags) {
1647        self.flags = flags;
1648    }
1649    fn current_flags(&self) -> crate::ParamFlags {
1650        self.flags
1651    }
1652}
1653
1654wrapper! {
1655    /// A [`ParamSpec`][crate::ParamSpec] derived structure that contains the meta data for `G_TYPE_PARAM`
1656    /// properties.
1657    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1658    #[doc(alias = "GParamSpecParam")]
1659    pub struct ParamSpecParam(Shared<gobject_ffi::GParamSpecParam>);
1660
1661    match fn {
1662        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut gobject_ffi::GParamSpecParam,
1663        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
1664    }
1665}
1666define_param_spec!(ParamSpecParam, gobject_ffi::GParamSpecParam, "GParamParam");
1667
1668impl ParamSpecParam {
1669    unsafe fn new_unchecked<'a>(
1670        name: &str,
1671        nick: impl Into<Option<&'a str>>,
1672        blurb: impl Into<Option<&'a str>>,
1673        param_type: crate::Type,
1674        flags: ParamFlags,
1675    ) -> ParamSpec {
1676        assert!(param_type.is_a(crate::Type::PARAM_SPEC));
1677        unsafe {
1678            from_glib_none(gobject_ffi::g_param_spec_param(
1679                name.to_glib_none().0,
1680                nick.into().to_glib_none().0,
1681                blurb.into().to_glib_none().0,
1682                param_type.into_glib(),
1683                flags.into_glib(),
1684            ))
1685        }
1686    }
1687}
1688
1689define_builder!(
1690    ParamSpecParam,
1691    "g_param_spec_param",
1692    ParamSpecParamBuilder {
1693        param_type: crate::Type,
1694    }
1695    requires (param_type: crate::Type,)
1696);
1697
1698wrapper! {
1699    /// A [`ParamSpec`][crate::ParamSpec] derived structure that contains the meta data for boxed properties.
1700    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1701    #[doc(alias = "GParamSpecBoxed")]
1702    pub struct ParamSpecBoxed(Shared<gobject_ffi::GParamSpecBoxed>);
1703
1704    match fn {
1705        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut gobject_ffi::GParamSpecBoxed,
1706        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
1707    }
1708}
1709define_param_spec!(ParamSpecBoxed, gobject_ffi::GParamSpecBoxed, "GParamBoxed");
1710
1711impl ParamSpecBoxed {
1712    unsafe fn new_unchecked<'a>(
1713        name: &str,
1714        nick: impl Into<Option<&'a str>>,
1715        blurb: impl Into<Option<&'a str>>,
1716        boxed_type: crate::Type,
1717        flags: ParamFlags,
1718    ) -> ParamSpec {
1719        unsafe {
1720            from_glib_none(gobject_ffi::g_param_spec_boxed(
1721                name.to_glib_none().0,
1722                nick.into().to_glib_none().0,
1723                blurb.into().to_glib_none().0,
1724                boxed_type.into_glib(),
1725                flags.into_glib(),
1726            ))
1727        }
1728    }
1729
1730    #[doc(alias = "g_param_spec_boxed")]
1731    pub fn builder<T: StaticType>(name: &str) -> ParamSpecBoxedBuilder<T> {
1732        ParamSpecBoxedBuilder::new(name)
1733    }
1734}
1735
1736#[must_use]
1737pub struct ParamSpecBoxedBuilder<'a, T: StaticType> {
1738    name: &'a str,
1739    nick: Option<&'a str>,
1740    blurb: Option<&'a str>,
1741    flags: crate::ParamFlags,
1742    phantom: std::marker::PhantomData<T>,
1743}
1744
1745impl<'a, T: StaticType> ParamSpecBoxedBuilder<'a, T> {
1746    fn new(name: &'a str) -> Self {
1747        assert_param_name(name);
1748        assert!(T::static_type().is_a(Type::BOXED));
1749        Self {
1750            name,
1751            nick: None,
1752            blurb: None,
1753            flags: crate::ParamFlags::default(),
1754            phantom: Default::default(),
1755        }
1756    }
1757
1758    #[must_use]
1759    pub fn build(self) -> ParamSpec {
1760        unsafe {
1761            ParamSpecBoxed::new_unchecked(
1762                self.name,
1763                self.nick,
1764                self.blurb,
1765                T::static_type(),
1766                self.flags,
1767            )
1768        }
1769    }
1770}
1771
1772impl<'a, T: StaticType> crate::prelude::ParamSpecBuilderExt<'a> for ParamSpecBoxedBuilder<'a, T> {
1773    fn set_nick(&mut self, nick: Option<&'a str>) {
1774        self.nick = nick;
1775    }
1776    fn set_blurb(&mut self, blurb: Option<&'a str>) {
1777        self.blurb = blurb;
1778    }
1779    fn set_flags(&mut self, flags: crate::ParamFlags) {
1780        self.flags = flags;
1781    }
1782    fn current_flags(&self) -> crate::ParamFlags {
1783        self.flags
1784    }
1785}
1786
1787wrapper! {
1788    /// A [`ParamSpec`][crate::ParamSpec] derived structure that contains the meta data for pointer properties.
1789    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1790    #[doc(alias = "GParamSpecPointer")]
1791    pub struct ParamSpecPointer(Shared<gobject_ffi::GParamSpecPointer>);
1792
1793    match fn {
1794        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut gobject_ffi::GParamSpecPointer,
1795        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
1796    }
1797}
1798define_param_spec!(
1799    ParamSpecPointer,
1800    gobject_ffi::GParamSpecPointer,
1801    "GParamPointer"
1802);
1803
1804impl ParamSpecPointer {
1805    unsafe fn new_unchecked<'a>(
1806        name: &str,
1807        nick: impl Into<Option<&'a str>>,
1808        blurb: impl Into<Option<&'a str>>,
1809        flags: ParamFlags,
1810    ) -> ParamSpec {
1811        unsafe {
1812            from_glib_none(gobject_ffi::g_param_spec_pointer(
1813                name.to_glib_none().0,
1814                nick.into().to_glib_none().0,
1815                blurb.into().to_glib_none().0,
1816                flags.into_glib(),
1817            ))
1818        }
1819    }
1820}
1821
1822define_builder!(
1823    ParamSpecPointer,
1824    "g_param_spec_pointer",
1825    ParamSpecPointerBuilder {}
1826);
1827
1828wrapper! {
1829    /// A [`ParamSpec`][crate::ParamSpec] derived structure that contains the meta data for `GValueArray` properties.
1830    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1831    #[doc(alias = "GParamSpecValueArray")]
1832    pub struct ParamSpecValueArray(Shared<gobject_ffi::GParamSpecValueArray>);
1833
1834    match fn {
1835        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut gobject_ffi::GParamSpecValueArray,
1836        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
1837    }
1838}
1839define_param_spec!(
1840    ParamSpecValueArray,
1841    gobject_ffi::GParamSpecValueArray,
1842    "GParamValueArray"
1843);
1844
1845impl ParamSpecValueArray {
1846    unsafe fn new_unchecked<'a>(
1847        name: &str,
1848        nick: impl Into<Option<&'a str>>,
1849        blurb: impl Into<Option<&'a str>>,
1850        element_spec: Option<impl AsRef<ParamSpec>>,
1851        flags: ParamFlags,
1852    ) -> ParamSpec {
1853        unsafe {
1854            from_glib_none(gobject_ffi::g_param_spec_value_array(
1855                name.to_glib_none().0,
1856                nick.into().to_glib_none().0,
1857                blurb.into().to_glib_none().0,
1858                element_spec.as_ref().map(|p| p.as_ref()).to_glib_none().0,
1859                flags.into_glib(),
1860            ))
1861        }
1862    }
1863
1864    #[doc(alias = "get_element_spec")]
1865    #[inline]
1866    pub fn element_spec(&self) -> Option<&ParamSpec> {
1867        unsafe {
1868            let ptr = ToGlibPtr::<*const gobject_ffi::GParamSpecValueArray>::to_glib_none(self).0;
1869
1870            if (*ptr).element_spec.is_null() {
1871                None
1872            } else {
1873                Some(
1874                    &*(&(*ptr).element_spec as *const *mut gobject_ffi::GParamSpec
1875                        as *const ParamSpec),
1876                )
1877            }
1878        }
1879    }
1880
1881    #[doc(alias = "get_fixed_n_elements")]
1882    #[inline]
1883    pub fn fixed_n_elements(&self) -> u32 {
1884        unsafe {
1885            let ptr = ToGlibPtr::<*const gobject_ffi::GParamSpecValueArray>::to_glib_none(self).0;
1886
1887            (*ptr).fixed_n_elements
1888        }
1889    }
1890
1891    #[doc(alias = "g_param_spec_value_array")]
1892    pub fn builder(name: &str) -> ParamSpecValueArrayBuilder {
1893        ParamSpecValueArrayBuilder::new(name)
1894    }
1895}
1896
1897#[must_use]
1898pub struct ParamSpecValueArrayBuilder<'a> {
1899    name: &'a str,
1900    nick: Option<&'a str>,
1901    blurb: Option<&'a str>,
1902    flags: crate::ParamFlags,
1903    element_spec: Option<&'a ParamSpec>,
1904}
1905
1906impl<'a> ParamSpecValueArrayBuilder<'a> {
1907    fn new(name: &'a str) -> Self {
1908        assert_param_name(name);
1909        Self {
1910            name,
1911            nick: None,
1912            blurb: None,
1913            flags: crate::ParamFlags::default(),
1914            element_spec: None,
1915        }
1916    }
1917
1918    #[doc = "Default: None`"]
1919    pub fn element_spec(mut self, value: impl Into<Option<&'a ParamSpec>>) -> Self {
1920        self.element_spec = value.into();
1921        self
1922    }
1923
1924    #[must_use]
1925    pub fn build(self) -> ParamSpec {
1926        unsafe {
1927            ParamSpecValueArray::new_unchecked(
1928                self.name,
1929                self.nick,
1930                self.blurb,
1931                self.element_spec,
1932                self.flags,
1933            )
1934        }
1935    }
1936}
1937
1938impl<'a> crate::prelude::ParamSpecBuilderExt<'a> for ParamSpecValueArrayBuilder<'a> {
1939    fn set_nick(&mut self, nick: Option<&'a str>) {
1940        self.nick = nick;
1941    }
1942    fn set_blurb(&mut self, blurb: Option<&'a str>) {
1943        self.blurb = blurb;
1944    }
1945    fn set_flags(&mut self, flags: crate::ParamFlags) {
1946        self.flags = flags;
1947    }
1948    fn current_flags(&self) -> crate::ParamFlags {
1949        self.flags
1950    }
1951}
1952
1953wrapper! {
1954    /// A [`ParamSpec`][crate::ParamSpec] derived structure that contains the meta data for object properties.
1955    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1956    #[doc(alias = "GParamSpecObject")]
1957    pub struct ParamSpecObject(Shared<gobject_ffi::GParamSpecObject>);
1958
1959    match fn {
1960        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut gobject_ffi::GParamSpecObject,
1961        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
1962    }
1963}
1964define_param_spec!(
1965    ParamSpecObject,
1966    gobject_ffi::GParamSpecObject,
1967    "GParamObject"
1968);
1969
1970impl ParamSpecObject {
1971    unsafe fn new_unchecked<'a>(
1972        name: &str,
1973        nick: impl Into<Option<&'a str>>,
1974        blurb: impl Into<Option<&'a str>>,
1975        object_type: crate::Type,
1976        flags: ParamFlags,
1977    ) -> ParamSpec {
1978        unsafe {
1979            from_glib_none(gobject_ffi::g_param_spec_object(
1980                name.to_glib_none().0,
1981                nick.into().to_glib_none().0,
1982                blurb.into().to_glib_none().0,
1983                object_type.into_glib(),
1984                flags.into_glib(),
1985            ))
1986        }
1987    }
1988
1989    #[doc(alias = "g_param_spec_object")]
1990    pub fn builder<T: StaticType + IsA<Object>>(name: &str) -> ParamSpecObjectBuilder<T> {
1991        ParamSpecObjectBuilder::new(name)
1992    }
1993}
1994
1995#[must_use]
1996pub struct ParamSpecObjectBuilder<'a, T: StaticType> {
1997    name: &'a str,
1998    nick: Option<&'a str>,
1999    blurb: Option<&'a str>,
2000    flags: crate::ParamFlags,
2001    phantom: std::marker::PhantomData<T>,
2002}
2003
2004impl<'a, T: StaticType> ParamSpecObjectBuilder<'a, T> {
2005    fn new(name: &'a str) -> Self {
2006        assert_param_name(name);
2007
2008        Self {
2009            name,
2010            nick: None,
2011            blurb: None,
2012            flags: crate::ParamFlags::default(),
2013            phantom: Default::default(),
2014        }
2015    }
2016
2017    #[must_use]
2018    pub fn build(self) -> ParamSpec {
2019        unsafe {
2020            ParamSpecObject::new_unchecked(
2021                self.name,
2022                self.nick,
2023                self.blurb,
2024                T::static_type(),
2025                self.flags,
2026            )
2027        }
2028    }
2029}
2030
2031impl<'a, T: StaticType> crate::prelude::ParamSpecBuilderExt<'a> for ParamSpecObjectBuilder<'a, T> {
2032    fn set_nick(&mut self, nick: Option<&'a str>) {
2033        self.nick = nick;
2034    }
2035    fn set_blurb(&mut self, blurb: Option<&'a str>) {
2036        self.blurb = blurb;
2037    }
2038    fn set_flags(&mut self, flags: crate::ParamFlags) {
2039        self.flags = flags;
2040    }
2041    fn current_flags(&self) -> crate::ParamFlags {
2042        self.flags
2043    }
2044}
2045
2046wrapper! {
2047    /// A [`ParamSpec`][crate::ParamSpec] derived structure that redirects operations to
2048    /// other types of [`ParamSpec`][crate::ParamSpec].
2049    ///
2050    /// All operations other than getting or setting the value are redirected,
2051    /// including accessing the nick and blurb, validating a value, and so
2052    /// forth.
2053    ///
2054    /// See [`ParamSpec::redirect_target()`][crate::ParamSpec::redirect_target()] for retrieving the overridden
2055    /// property. [`ParamSpecOverride`][crate::ParamSpecOverride] is used in implementing
2056    /// `g_object_class_override_property()`, and will not be directly useful
2057    /// unless you are implementing a new base type similar to GObject.
2058    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
2059    #[doc(alias = "GParamSpecOverride")]
2060    pub struct ParamSpecOverride(Shared<gobject_ffi::GParamSpecOverride>);
2061
2062    match fn {
2063        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut gobject_ffi::GParamSpecOverride,
2064        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
2065    }
2066}
2067define_param_spec!(
2068    ParamSpecOverride,
2069    gobject_ffi::GParamSpecOverride,
2070    "GParamOverride"
2071);
2072
2073impl ParamSpecOverride {
2074    unsafe fn new_unchecked(name: &str, overridden: impl AsRef<ParamSpec>) -> ParamSpec {
2075        from_glib_none(gobject_ffi::g_param_spec_override(
2076            name.to_glib_none().0,
2077            overridden.as_ref().to_glib_none().0,
2078        ))
2079    }
2080
2081    // rustdoc-stripper-ignore-next
2082    /// Create a [`ParamSpecOverride`] to override an interface property.
2083    ///
2084    /// # Examples
2085    ///
2086    /// ```ignore
2087    /// let pspec = ParamSpecOverride::for_interface::<gtk::Scrollable>("vadjustment");
2088    /// ```
2089    ///
2090    /// # Panics
2091    ///
2092    /// If the property `name` doesn't exist in the interface.
2093    #[allow(clippy::new_ret_no_self)]
2094    #[doc(alias = "g_param_spec_override")]
2095    pub fn for_interface<T: IsA<Object> + IsInterface>(name: &str) -> ParamSpec {
2096        assert_param_name(name);
2097        // in case it's an interface
2098        let interface_ref: InterfaceRef<T> = Interface::from_type(T::static_type()).unwrap();
2099        let pspec = interface_ref
2100            .find_property(name)
2101            .unwrap_or_else(|| panic!("Couldn't find a property named `{name}` to override"));
2102
2103        unsafe { Self::new_unchecked(name, &pspec) }
2104    }
2105
2106    // rustdoc-stripper-ignore-next
2107    /// Create a [`ParamSpecOverride`] to override a class property.
2108    ///
2109    /// # Examples
2110    ///
2111    /// ```rust, ignore
2112    /// let pspec = ParamSpecOverride::for_class::<gtk::Button>("label");
2113    /// ```
2114    ///
2115    /// # Panics
2116    ///
2117    /// If the property `name` doesn't exist in the class.
2118    #[allow(clippy::new_ret_no_self)]
2119    #[doc(alias = "g_param_spec_override")]
2120    pub fn for_class<T: IsA<Object> + IsClass>(name: &str) -> ParamSpec {
2121        assert_param_name(name);
2122        let pspec = ObjectClass::from_type(T::static_type())
2123            .unwrap()
2124            .find_property(name)
2125            .unwrap_or_else(|| panic!("Couldn't find a property named `{name}` to override"));
2126
2127        unsafe { Self::new_unchecked(name, &pspec) }
2128    }
2129
2130    #[doc(alias = "get_overridden")]
2131    #[inline]
2132    pub fn overridden(&self) -> ParamSpec {
2133        unsafe {
2134            let ptr = ToGlibPtr::<*const gobject_ffi::GParamSpecOverride>::to_glib_none(self).0;
2135
2136            from_glib_none((*ptr).overridden)
2137        }
2138    }
2139
2140    #[doc(alias = "g_param_spec_override")]
2141    pub fn builder<'a>(name: &'a str, overridden: &'a ParamSpec) -> ParamSpecOverrideBuilder<'a> {
2142        ParamSpecOverrideBuilder::new(name, overridden)
2143    }
2144}
2145
2146// This builder is not autogenerated because it's the only one that doesn't take
2147// `nick`, `blurb` and `flags` as parameters.
2148#[must_use]
2149pub struct ParamSpecOverrideBuilder<'a> {
2150    name: &'a str,
2151    overridden: &'a ParamSpec,
2152}
2153
2154impl<'a> ParamSpecOverrideBuilder<'a> {
2155    fn new(name: &'a str, overridden: &'a ParamSpec) -> Self {
2156        assert_param_name(name);
2157        Self { name, overridden }
2158    }
2159    pub fn overridden(mut self, spec: &'a ParamSpec) -> Self {
2160        self.overridden = spec;
2161        self
2162    }
2163    #[must_use]
2164    pub fn build(self) -> ParamSpec {
2165        unsafe { ParamSpecOverride::new_unchecked(self.name, self.overridden) }
2166    }
2167}
2168
2169wrapper! {
2170    /// A [`ParamSpec`][crate::ParamSpec] derived structure that contains the meta data for `GType` properties.
2171    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
2172    #[doc(alias = "GParamSpecGType")]
2173    pub struct ParamSpecGType(Shared<gobject_ffi::GParamSpecGType>);
2174
2175    match fn {
2176        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut gobject_ffi::GParamSpecGType,
2177        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
2178    }
2179}
2180define_param_spec!(ParamSpecGType, gobject_ffi::GParamSpecGType, "GParamGType");
2181
2182impl ParamSpecGType {
2183    unsafe fn new_unchecked<'a>(
2184        name: &str,
2185        nick: impl Into<Option<&'a str>>,
2186        blurb: impl Into<Option<&'a str>>,
2187        is_a_type: crate::Type,
2188        flags: ParamFlags,
2189    ) -> ParamSpec {
2190        unsafe {
2191            from_glib_none(gobject_ffi::g_param_spec_gtype(
2192                name.to_glib_none().0,
2193                nick.into().to_glib_none().0,
2194                blurb.into().to_glib_none().0,
2195                is_a_type.into_glib(),
2196                flags.into_glib(),
2197            ))
2198        }
2199    }
2200}
2201
2202define_builder!(
2203    ParamSpecGType,
2204    "g_param_spec_gtype",
2205    ParamSpecGTypeBuilder {
2206        is_a_type: crate::Type = crate::Type::UNIT,
2207    }
2208);
2209
2210wrapper! {
2211    /// A [`ParamSpec`][crate::ParamSpec] derived structure that contains the meta data for `GVariant` properties.
2212    ///
2213    /// When comparing values with `g_param_values_cmp()`, scalar values with the same
2214    /// type will be compared with `g_variant_compare()`. Other non-[`None`] variants will
2215    /// be checked for equality with `g_variant_equal()`, and their sort order is
2216    /// otherwise undefined. [`None`] is ordered before non-[`None`] variants. Two [`None`]
2217    /// values compare equal.
2218    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
2219    #[doc(alias = "GParamSpecVariant")]
2220    pub struct ParamSpecVariant(Shared<gobject_ffi::GParamSpecVariant>);
2221
2222    match fn {
2223        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut gobject_ffi::GParamSpecVariant,
2224        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
2225    }
2226}
2227define_param_spec!(
2228    ParamSpecVariant,
2229    gobject_ffi::GParamSpecVariant,
2230    "GParamVariant"
2231);
2232
2233define_param_spec_default!(
2234    ParamSpecVariant,
2235    gobject_ffi::GParamSpecVariant,
2236    Option<crate::Variant>,
2237    |x: *mut ffi::GVariant| from_glib_none(x)
2238);
2239
2240impl ParamSpecVariant {
2241    unsafe fn new_unchecked<'a>(
2242        name: &str,
2243        nick: impl Into<Option<&'a str>>,
2244        blurb: impl Into<Option<&'a str>>,
2245        type_: &crate::VariantTy,
2246        default_value: Option<&crate::Variant>,
2247        flags: ParamFlags,
2248    ) -> ParamSpec {
2249        unsafe {
2250            from_glib_none(gobject_ffi::g_param_spec_variant(
2251                name.to_glib_none().0,
2252                nick.into().to_glib_none().0,
2253                blurb.into().to_glib_none().0,
2254                type_.to_glib_none().0,
2255                default_value.to_glib_none().0,
2256                flags.into_glib(),
2257            ))
2258        }
2259    }
2260
2261    #[doc(alias = "get_type")]
2262    #[inline]
2263    pub fn type_(&self) -> Option<&crate::VariantTy> {
2264        unsafe {
2265            let ptr = ToGlibPtr::<*const gobject_ffi::GParamSpecVariant>::to_glib_none(self).0;
2266
2267            if (*ptr).type_.is_null() {
2268                None
2269            } else {
2270                Some(crate::VariantTy::from_ptr((*ptr).type_))
2271            }
2272        }
2273    }
2274
2275    #[doc(alias = "g_param_spec_variant")]
2276    pub fn builder<'a>(name: &'a str, type_: &'a crate::VariantTy) -> ParamSpecVariantBuilder<'a> {
2277        ParamSpecVariantBuilder::new(name, type_)
2278    }
2279}
2280
2281#[must_use]
2282pub struct ParamSpecVariantBuilder<'a> {
2283    name: &'a str,
2284    nick: Option<&'a str>,
2285    blurb: Option<&'a str>,
2286    flags: crate::ParamFlags,
2287    type_: &'a crate::VariantTy,
2288    default_value: Option<&'a crate::Variant>,
2289}
2290
2291impl<'a> ParamSpecVariantBuilder<'a> {
2292    fn new(name: &'a str, type_: &'a crate::VariantTy) -> Self {
2293        assert_param_name(name);
2294        Self {
2295            name,
2296            nick: None,
2297            blurb: None,
2298            flags: crate::ParamFlags::default(),
2299            type_,
2300            default_value: None,
2301        }
2302    }
2303
2304    #[doc = "Default: None`"]
2305    pub fn default_value(mut self, value: impl Into<Option<&'a crate::Variant>>) -> Self {
2306        self.default_value = value.into();
2307        self
2308    }
2309
2310    #[must_use]
2311    pub fn build(self) -> ParamSpec {
2312        unsafe {
2313            ParamSpecVariant::new_unchecked(
2314                self.name,
2315                self.nick,
2316                self.blurb,
2317                self.type_,
2318                self.default_value,
2319                self.flags,
2320            )
2321        }
2322    }
2323}
2324
2325impl<'a> crate::prelude::ParamSpecBuilderExt<'a> for ParamSpecVariantBuilder<'a> {
2326    fn set_nick(&mut self, nick: Option<&'a str>) {
2327        self.nick = nick;
2328    }
2329    fn set_blurb(&mut self, blurb: Option<&'a str>) {
2330        self.blurb = blurb;
2331    }
2332    fn set_flags(&mut self, flags: crate::ParamFlags) {
2333        self.flags = flags;
2334    }
2335    fn current_flags(&self) -> crate::ParamFlags {
2336        self.flags
2337    }
2338}
2339
2340pub trait HasParamSpec {
2341    type ParamSpec;
2342
2343    // rustdoc-stripper-ignore-next
2344    /// Preferred value to be used as setter for the associated ParamSpec.
2345    type SetValue: ?Sized;
2346    type BuilderFn;
2347    fn param_spec_builder() -> Self::BuilderFn;
2348}
2349
2350impl<T: crate::value::ToValueOptional + HasParamSpec> HasParamSpec for Option<T> {
2351    type ParamSpec = T::ParamSpec;
2352    type SetValue = T::SetValue;
2353    type BuilderFn = T::BuilderFn;
2354
2355    fn param_spec_builder() -> Self::BuilderFn {
2356        T::param_spec_builder()
2357    }
2358}
2359impl<T: HasParamSpec + ?Sized> HasParamSpec for &T {
2360    type ParamSpec = T::ParamSpec;
2361    type SetValue = T::SetValue;
2362    type BuilderFn = T::BuilderFn;
2363
2364    fn param_spec_builder() -> Self::BuilderFn {
2365        T::param_spec_builder()
2366    }
2367}
2368impl HasParamSpec for crate::GString {
2369    type ParamSpec = ParamSpecString;
2370    type SetValue = str;
2371    type BuilderFn = fn(&str) -> ParamSpecStringBuilder;
2372
2373    fn param_spec_builder() -> Self::BuilderFn {
2374        Self::ParamSpec::builder
2375    }
2376}
2377impl HasParamSpec for str {
2378    type ParamSpec = ParamSpecString;
2379    type SetValue = str;
2380    type BuilderFn = fn(&str) -> ParamSpecStringBuilder;
2381
2382    fn param_spec_builder() -> Self::BuilderFn {
2383        Self::ParamSpec::builder
2384    }
2385}
2386impl HasParamSpec for String {
2387    type ParamSpec = ParamSpecString;
2388    type SetValue = str;
2389    type BuilderFn = fn(&str) -> ParamSpecStringBuilder;
2390
2391    fn param_spec_builder() -> Self::BuilderFn {
2392        Self::ParamSpec::builder
2393    }
2394}
2395impl HasParamSpec for Box<str> {
2396    type ParamSpec = ParamSpecString;
2397    type SetValue = str;
2398    type BuilderFn = fn(&str) -> ParamSpecStringBuilder;
2399
2400    fn param_spec_builder() -> Self::BuilderFn {
2401        Self::ParamSpec::builder
2402    }
2403}
2404impl HasParamSpec for crate::StrV {
2405    type ParamSpec = ParamSpecBoxed;
2406    type SetValue = Self;
2407    type BuilderFn = fn(&str) -> ParamSpecBoxedBuilder<Self>;
2408
2409    fn param_spec_builder() -> Self::BuilderFn {
2410        Self::ParamSpec::builder
2411    }
2412}
2413impl HasParamSpec for Vec<String> {
2414    type ParamSpec = ParamSpecBoxed;
2415    type SetValue = Self;
2416    type BuilderFn = fn(&str) -> ParamSpecBoxedBuilder<Self>;
2417
2418    fn param_spec_builder() -> Self::BuilderFn {
2419        Self::ParamSpec::builder
2420    }
2421}
2422impl HasParamSpec for Path {
2423    type ParamSpec = ParamSpecString;
2424    type SetValue = Path;
2425    type BuilderFn = fn(&str) -> ParamSpecStringBuilder;
2426
2427    fn param_spec_builder() -> Self::BuilderFn {
2428        Self::ParamSpec::builder
2429    }
2430}
2431impl HasParamSpec for PathBuf {
2432    type ParamSpec = ParamSpecString;
2433    type SetValue = Path;
2434    type BuilderFn = fn(&str) -> ParamSpecStringBuilder;
2435
2436    fn param_spec_builder() -> Self::BuilderFn {
2437        Self::ParamSpec::builder
2438    }
2439}
2440impl HasParamSpec for char {
2441    type ParamSpec = ParamSpecUnichar;
2442    type SetValue = Self;
2443    type BuilderFn = fn(&str, char) -> ParamSpecUnicharBuilder;
2444
2445    fn param_spec_builder() -> Self::BuilderFn {
2446        Self::ParamSpec::builder
2447    }
2448}
2449// Simple types which have `type SetValue = Self`
2450// and a builder function that doesn't require any parameter except the name
2451macro_rules! has_simple_spec {
2452    ($t:ty, $s:ty, $b:ty) => {
2453        impl HasParamSpec for $t {
2454            type ParamSpec = $s;
2455            type SetValue = Self;
2456            type BuilderFn = fn(&str) -> $b;
2457
2458            fn param_spec_builder() -> Self::BuilderFn {
2459                Self::ParamSpec::builder
2460            }
2461        }
2462    };
2463}
2464has_simple_spec!(f64, ParamSpecDouble, ParamSpecDoubleBuilder);
2465has_simple_spec!(f32, ParamSpecFloat, ParamSpecFloatBuilder);
2466has_simple_spec!(i64, ParamSpecInt64, ParamSpecInt64Builder);
2467has_simple_spec!(NonZeroI64, ParamSpecInt64, ParamSpecInt64Builder);
2468has_simple_spec!(i32, ParamSpecInt, ParamSpecIntBuilder);
2469has_simple_spec!(NonZeroI32, ParamSpecInt, ParamSpecIntBuilder);
2470has_simple_spec!(i8, ParamSpecChar, ParamSpecCharBuilder);
2471has_simple_spec!(NonZeroI8, ParamSpecChar, ParamSpecCharBuilder);
2472has_simple_spec!(u64, ParamSpecUInt64, ParamSpecUInt64Builder);
2473has_simple_spec!(NonZeroU64, ParamSpecUInt64, ParamSpecUInt64Builder);
2474has_simple_spec!(u32, ParamSpecUInt, ParamSpecUIntBuilder);
2475has_simple_spec!(NonZeroU32, ParamSpecUInt, ParamSpecUIntBuilder);
2476has_simple_spec!(u8, ParamSpecUChar, ParamSpecUCharBuilder);
2477has_simple_spec!(NonZeroU8, ParamSpecUChar, ParamSpecUCharBuilder);
2478has_simple_spec!(bool, ParamSpecBoolean, ParamSpecBooleanBuilder);
2479
2480impl HasParamSpec for crate::Variant {
2481    type ParamSpec = ParamSpecVariant;
2482    type SetValue = Self;
2483    type BuilderFn = for<'a> fn(&'a str, ty: &'a crate::VariantTy) -> ParamSpecVariantBuilder<'a>;
2484
2485    fn param_spec_builder() -> Self::BuilderFn {
2486        Self::ParamSpec::builder
2487    }
2488}
2489
2490#[cfg(test)]
2491mod tests {
2492    use super::*;
2493
2494    #[test]
2495    fn test_param_spec_string() {
2496        let pspec = ParamSpecString::builder("name")
2497            .default_value(Some("default"))
2498            .build();
2499
2500        assert_eq!(pspec.name(), "name");
2501        assert_eq!(pspec.nick(), "name");
2502        assert_eq!(pspec.blurb(), None);
2503        let default_value = pspec.default_value();
2504        assert_eq!(default_value.get::<&str>().unwrap(), "default");
2505        assert_eq!(pspec.flags(), ParamFlags::READWRITE);
2506        assert_eq!(pspec.value_type(), Type::STRING);
2507        assert_eq!(pspec.type_(), ParamSpecString::static_type());
2508
2509        let pspec_ref = pspec
2510            .downcast_ref::<ParamSpecString>()
2511            .expect("Not a string param spec");
2512        assert_eq!(pspec_ref.default_value(), Some("default"));
2513
2514        let pspec = pspec
2515            .downcast::<ParamSpecString>()
2516            .expect("Not a string param spec");
2517        assert_eq!(pspec.default_value(), Some("default"));
2518    }
2519
2520    #[test]
2521    fn test_param_spec_int_builder() {
2522        let pspec = ParamSpecInt::builder("name")
2523            .blurb("Simple int parameter")
2524            .minimum(-2)
2525            .explicit_notify()
2526            .build();
2527
2528        assert_eq!(pspec.name(), "name");
2529        assert_eq!(pspec.nick(), "name");
2530        assert_eq!(pspec.blurb(), Some("Simple int parameter"));
2531        assert_eq!(
2532            pspec.flags(),
2533            ParamFlags::READWRITE | ParamFlags::EXPLICIT_NOTIFY
2534        );
2535    }
2536
2537    #[test]
2538    fn test_param_spec_builder_flags() {
2539        let pspec = ParamSpecInt::builder("name")
2540            .minimum(-2)
2541            .read_only()
2542            .build()
2543            .downcast::<ParamSpecInt>()
2544            .unwrap();
2545        assert_eq!(pspec.minimum(), -2);
2546        assert_eq!(pspec.flags(), ParamFlags::READABLE);
2547
2548        let pspec = ParamSpecInt::builder("name")
2549            .read_only()
2550            .write_only()
2551            .minimum(-2)
2552            .build()
2553            .downcast::<ParamSpecInt>()
2554            .unwrap();
2555        assert_eq!(pspec.minimum(), -2);
2556        assert_eq!(pspec.flags(), ParamFlags::WRITABLE);
2557
2558        let pspec = ParamSpecInt::builder("name")
2559            .read_only()
2560            .write_only()
2561            .readwrite()
2562            .minimum(-2)
2563            .build()
2564            .downcast::<ParamSpecInt>()
2565            .unwrap();
2566        assert_eq!(pspec.minimum(), -2);
2567        assert_eq!(pspec.flags(), ParamFlags::READWRITE);
2568    }
2569
2570    #[test]
2571    fn test_has_param_spec() {
2572        let pspec = <i32 as HasParamSpec>::param_spec_builder()("name")
2573            .blurb("Simple int parameter")
2574            .minimum(-2)
2575            .explicit_notify()
2576            .build();
2577
2578        assert_eq!(pspec.name(), "name");
2579        assert_eq!(pspec.blurb(), Some("Simple int parameter"));
2580        assert_eq!(
2581            pspec.flags(),
2582            ParamFlags::READWRITE | ParamFlags::EXPLICIT_NOTIFY
2583        );
2584    }
2585}