glib/
param_spec.rs

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