glib/
param_spec.rs

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