Skip to main content

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