glib/
param_spec.rs

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