glib/
param_spec.rs

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