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