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