Skip to main content

glib/
param_spec.rs

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