gstreamer/
value.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{cmp, fmt, ops, slice};
4
5use crate::ffi;
6use glib::{prelude::*, translate::*};
7use num_rational::Rational32;
8
9#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
10pub struct Fraction(pub Rational32);
11
12impl Fraction {
13    // rustdoc-stripper-ignore-next
14    /// Creates a new `Ratio`.
15    ///
16    /// # Panics
17    ///
18    /// Panics if `denom` is zero.
19    #[inline]
20    pub fn new(numer: i32, denom: i32) -> Self {
21        skip_assert_initialized!();
22        (numer, denom).into()
23    }
24
25    // rustdoc-stripper-ignore-next
26    /// Creates a `Fraction` without checking for `denom == 0` or reducing.
27    ///
28    /// While this does not panic, there are several methods that will panic
29    /// if used on a `Fraction` with `denom == 0`.
30    #[inline]
31    pub const fn new_raw(numer: i32, denom: i32) -> Self {
32        skip_assert_initialized!();
33        Self(Rational32::new_raw(numer, denom))
34    }
35
36    // rustdoc-stripper-ignore-next
37    /// Creates a `Fraction` representing the integer `t`.
38    #[inline]
39    pub const fn from_integer(t: i32) -> Self {
40        skip_assert_initialized!();
41        Self::new_raw(t, 1)
42    }
43
44    pub fn approximate_f32(x: f32) -> Option<Self> {
45        skip_assert_initialized!();
46        Rational32::approximate_float(x).map(|r| r.into())
47    }
48
49    pub fn approximate_f64(x: f64) -> Option<Self> {
50        skip_assert_initialized!();
51        Rational32::approximate_float(x).map(|r| r.into())
52    }
53
54    #[inline]
55    pub fn numer(&self) -> i32 {
56        *self.0.numer()
57    }
58
59    #[inline]
60    pub fn denom(&self) -> i32 {
61        *self.0.denom()
62    }
63
64    #[cfg(feature = "v1_24")]
65    #[cfg_attr(docsrs, doc(cfg(feature = "v1_24")))]
66    #[doc(alias = "gst_util_simplify_fraction")]
67    pub fn simplify(&mut self, n_terms: u32, threshold: u32) {
68        skip_assert_initialized!();
69        unsafe {
70            let mut numer = self.numer();
71            let mut denom = self.denom();
72            ffi::gst_util_simplify_fraction(&mut numer, &mut denom, n_terms, threshold);
73            *self = Self::new(numer, denom);
74        }
75    }
76}
77
78impl fmt::Display for Fraction {
79    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
80        self.0.fmt(f)
81    }
82}
83
84impl ops::Deref for Fraction {
85    type Target = Rational32;
86
87    #[inline]
88    fn deref(&self) -> &Self::Target {
89        &self.0
90    }
91}
92
93impl ops::DerefMut for Fraction {
94    #[inline]
95    fn deref_mut(&mut self) -> &mut Rational32 {
96        &mut self.0
97    }
98}
99
100impl AsRef<Rational32> for Fraction {
101    #[inline]
102    fn as_ref(&self) -> &Rational32 {
103        &self.0
104    }
105}
106
107macro_rules! impl_fraction_binop {
108    ($name:ident, $f:ident, $name_assign:ident, $f_assign:ident) => {
109        impl ops::$name<Fraction> for Fraction {
110            type Output = Fraction;
111
112            #[inline]
113            fn $f(self, other: Fraction) -> Self::Output {
114                Fraction((self.0).$f(other.0))
115            }
116        }
117
118        impl ops::$name<Fraction> for &Fraction {
119            type Output = Fraction;
120
121            #[inline]
122            fn $f(self, other: Fraction) -> Self::Output {
123                Fraction((self.0).$f(other.0))
124            }
125        }
126
127        impl ops::$name<&Fraction> for Fraction {
128            type Output = Fraction;
129
130            #[inline]
131            fn $f(self, other: &Fraction) -> Self::Output {
132                Fraction((self.0).$f(other.0))
133            }
134        }
135
136        impl ops::$name<&Fraction> for &Fraction {
137            type Output = Fraction;
138
139            #[inline]
140            fn $f(self, other: &Fraction) -> Self::Output {
141                Fraction((self.0).$f(other.0))
142            }
143        }
144
145        impl ops::$name<i32> for Fraction {
146            type Output = Fraction;
147
148            #[inline]
149            fn $f(self, other: i32) -> Self::Output {
150                self.$f(Fraction::from(other))
151            }
152        }
153
154        impl ops::$name<i32> for &Fraction {
155            type Output = Fraction;
156
157            #[inline]
158            fn $f(self, other: i32) -> Self::Output {
159                self.$f(Fraction::from(other))
160            }
161        }
162
163        impl ops::$name<&i32> for Fraction {
164            type Output = Fraction;
165
166            #[inline]
167            fn $f(self, other: &i32) -> Self::Output {
168                self.$f(Fraction::from(*other))
169            }
170        }
171
172        impl ops::$name<&i32> for &Fraction {
173            type Output = Fraction;
174
175            #[inline]
176            fn $f(self, other: &i32) -> Self::Output {
177                self.$f(Fraction::from(*other))
178            }
179        }
180
181        impl ops::$name<Fraction> for i32 {
182            type Output = Fraction;
183
184            #[inline]
185            fn $f(self, other: Fraction) -> Self::Output {
186                Fraction::from(self).$f(other)
187            }
188        }
189
190        impl ops::$name<&Fraction> for i32 {
191            type Output = Fraction;
192
193            #[inline]
194            fn $f(self, other: &Fraction) -> Self::Output {
195                Fraction::from(self).$f(other)
196            }
197        }
198
199        impl ops::$name<Fraction> for &i32 {
200            type Output = Fraction;
201
202            #[inline]
203            fn $f(self, other: Fraction) -> Self::Output {
204                Fraction::from(*self).$f(other)
205            }
206        }
207
208        impl ops::$name<&Fraction> for &i32 {
209            type Output = Fraction;
210
211            #[inline]
212            fn $f(self, other: &Fraction) -> Self::Output {
213                Fraction::from(*self).$f(other)
214            }
215        }
216
217        impl ops::$name_assign<Fraction> for Fraction {
218            #[inline]
219            fn $f_assign(&mut self, other: Fraction) {
220                (self.0).$f_assign(other.0)
221            }
222        }
223
224        impl ops::$name_assign<&Fraction> for Fraction {
225            #[inline]
226            fn $f_assign(&mut self, other: &Fraction) {
227                (self.0).$f_assign(other.0)
228            }
229        }
230
231        impl ops::$name_assign<i32> for Fraction {
232            #[inline]
233            fn $f_assign(&mut self, other: i32) {
234                (self.0).$f_assign(other)
235            }
236        }
237
238        impl ops::$name_assign<&i32> for Fraction {
239            #[inline]
240            fn $f_assign(&mut self, other: &i32) {
241                (self.0).$f_assign(other)
242            }
243        }
244    };
245}
246
247impl_fraction_binop!(Add, add, AddAssign, add_assign);
248impl_fraction_binop!(Sub, sub, SubAssign, sub_assign);
249impl_fraction_binop!(Div, div, DivAssign, div_assign);
250impl_fraction_binop!(Mul, mul, MulAssign, mul_assign);
251impl_fraction_binop!(Rem, rem, RemAssign, rem_assign);
252
253impl ops::Neg for Fraction {
254    type Output = Fraction;
255
256    #[inline]
257    fn neg(self) -> Self::Output {
258        Fraction(self.0.neg())
259    }
260}
261
262impl ops::Neg for &Fraction {
263    type Output = Fraction;
264
265    #[inline]
266    fn neg(self) -> Self::Output {
267        Fraction(self.0.neg())
268    }
269}
270
271impl From<i32> for Fraction {
272    #[inline]
273    fn from(x: i32) -> Self {
274        skip_assert_initialized!();
275        Fraction(x.into())
276    }
277}
278
279impl From<(i32, i32)> for Fraction {
280    #[inline]
281    fn from(x: (i32, i32)) -> Self {
282        skip_assert_initialized!();
283        Fraction(x.into())
284    }
285}
286
287impl From<Fraction> for (i32, i32) {
288    #[inline]
289    fn from(f: Fraction) -> Self {
290        skip_assert_initialized!();
291        f.0.into()
292    }
293}
294
295impl From<Rational32> for Fraction {
296    #[inline]
297    fn from(x: Rational32) -> Self {
298        skip_assert_initialized!();
299        Fraction(x)
300    }
301}
302
303impl From<Fraction> for Rational32 {
304    #[inline]
305    fn from(x: Fraction) -> Self {
306        skip_assert_initialized!();
307        x.0
308    }
309}
310
311impl glib::types::StaticType for Fraction {
312    #[inline]
313    fn static_type() -> glib::types::Type {
314        unsafe { from_glib(ffi::gst_fraction_get_type()) }
315    }
316}
317
318impl glib::value::ValueType for Fraction {
319    type Type = Self;
320}
321
322unsafe impl<'a> glib::value::FromValue<'a> for Fraction {
323    type Checker = glib::value::GenericValueTypeChecker<Self>;
324
325    #[inline]
326    unsafe fn from_value(value: &'a glib::Value) -> Self {
327        skip_assert_initialized!();
328        let n = ffi::gst_value_get_fraction_numerator(value.to_glib_none().0);
329        let d = ffi::gst_value_get_fraction_denominator(value.to_glib_none().0);
330
331        Fraction::new(n, d)
332    }
333}
334
335impl glib::value::ToValue for Fraction {
336    #[inline]
337    fn to_value(&self) -> glib::Value {
338        let mut value = glib::Value::for_value_type::<Self>();
339        unsafe {
340            ffi::gst_value_set_fraction(value.to_glib_none_mut().0, self.numer(), self.denom());
341        }
342        value
343    }
344
345    #[inline]
346    fn value_type(&self) -> glib::Type {
347        Self::static_type()
348    }
349}
350
351impl From<Fraction> for glib::Value {
352    #[inline]
353    fn from(v: Fraction) -> glib::Value {
354        skip_assert_initialized!();
355        glib::value::ToValue::to_value(&v)
356    }
357}
358
359#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
360#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
361pub struct IntRange<T> {
362    min: T,
363    max: T,
364    step: T,
365}
366
367impl<T: Copy> IntRange<T> {
368    #[inline]
369    pub fn min(&self) -> T {
370        self.min
371    }
372
373    #[inline]
374    pub fn max(&self) -> T {
375        self.max
376    }
377
378    #[inline]
379    pub fn step(&self) -> T {
380        self.step
381    }
382}
383
384#[doc(hidden)]
385pub trait IntRangeType: Sized + Clone + Copy + 'static {
386    fn with_min_max(min: Self, max: Self) -> IntRange<Self>;
387    fn with_step(min: Self, max: Self, step: Self) -> IntRange<Self>;
388}
389
390impl IntRangeType for i32 {
391    #[inline]
392    fn with_min_max(min: i32, max: i32) -> IntRange<Self> {
393        skip_assert_initialized!();
394        IntRange { min, max, step: 1 }
395    }
396
397    #[inline]
398    fn with_step(min: i32, max: i32, step: i32) -> IntRange<Self> {
399        skip_assert_initialized!();
400
401        assert!(
402            min < max,
403            "maximum value must be greater than minimum value"
404        );
405        assert!(step > 0, "step size must be greater than zero");
406        assert!(
407            min % step == 0,
408            "minimum value must be evenly dividable by step size"
409        );
410        assert!(
411            max % step == 0,
412            "maximum value must be evenly dividable by step size"
413        );
414
415        IntRange { min, max, step }
416    }
417}
418
419impl IntRangeType for i64 {
420    #[inline]
421    fn with_min_max(min: i64, max: i64) -> IntRange<Self> {
422        skip_assert_initialized!();
423        IntRange { min, max, step: 1 }
424    }
425
426    #[inline]
427    fn with_step(min: i64, max: i64, step: i64) -> IntRange<Self> {
428        skip_assert_initialized!();
429
430        assert!(
431            min < max,
432            "maximum value must be greater than minimum value"
433        );
434        assert!(step > 0, "step size must be greater than zero");
435        assert!(
436            min % step == 0,
437            "minimum value must be evenly dividable by step size"
438        );
439        assert!(
440            max % step == 0,
441            "maximum value must be evenly dividable by step size"
442        );
443
444        IntRange { min, max, step }
445    }
446}
447
448impl<T: IntRangeType> IntRange<T> {
449    #[inline]
450    pub fn new(min: T, max: T) -> IntRange<T> {
451        skip_assert_initialized!();
452        T::with_min_max(min, max)
453    }
454
455    #[inline]
456    pub fn with_step(min: T, max: T, step: T) -> IntRange<T> {
457        skip_assert_initialized!();
458        T::with_step(min, max, step)
459    }
460}
461
462impl From<(i32, i32)> for IntRange<i32> {
463    #[inline]
464    fn from((min, max): (i32, i32)) -> Self {
465        skip_assert_initialized!();
466        Self::new(min, max)
467    }
468}
469
470impl From<(i32, i32, i32)> for IntRange<i32> {
471    #[inline]
472    fn from((min, max, step): (i32, i32, i32)) -> Self {
473        skip_assert_initialized!();
474        Self::with_step(min, max, step)
475    }
476}
477
478impl From<(i64, i64)> for IntRange<i64> {
479    #[inline]
480    fn from((min, max): (i64, i64)) -> Self {
481        skip_assert_initialized!();
482        Self::new(min, max)
483    }
484}
485
486impl From<(i64, i64, i64)> for IntRange<i64> {
487    #[inline]
488    fn from((min, max, step): (i64, i64, i64)) -> Self {
489        skip_assert_initialized!();
490        Self::with_step(min, max, step)
491    }
492}
493
494impl glib::types::StaticType for IntRange<i32> {
495    #[inline]
496    fn static_type() -> glib::types::Type {
497        unsafe { from_glib(ffi::gst_int_range_get_type()) }
498    }
499}
500
501impl glib::value::ValueType for IntRange<i32> {
502    type Type = Self;
503}
504
505unsafe impl<'a> glib::value::FromValue<'a> for IntRange<i32> {
506    type Checker = glib::value::GenericValueTypeChecker<Self>;
507
508    #[inline]
509    unsafe fn from_value(value: &'a glib::Value) -> Self {
510        skip_assert_initialized!();
511        let min = ffi::gst_value_get_int_range_min(value.to_glib_none().0);
512        let max = ffi::gst_value_get_int_range_max(value.to_glib_none().0);
513        let step = ffi::gst_value_get_int_range_step(value.to_glib_none().0);
514
515        Self::with_step(min, max, step)
516    }
517}
518
519impl glib::value::ToValue for IntRange<i32> {
520    #[inline]
521    fn to_value(&self) -> glib::Value {
522        let mut value = glib::Value::for_value_type::<Self>();
523        unsafe {
524            ffi::gst_value_set_int_range_step(
525                value.to_glib_none_mut().0,
526                self.min(),
527                self.max(),
528                self.step(),
529            );
530        }
531        value
532    }
533
534    #[inline]
535    fn value_type(&self) -> glib::Type {
536        Self::static_type()
537    }
538}
539
540impl From<IntRange<i32>> for glib::Value {
541    #[inline]
542    fn from(v: IntRange<i32>) -> glib::Value {
543        skip_assert_initialized!();
544        glib::value::ToValue::to_value(&v)
545    }
546}
547
548impl glib::types::StaticType for IntRange<i64> {
549    #[inline]
550    fn static_type() -> glib::types::Type {
551        unsafe { from_glib(ffi::gst_int64_range_get_type()) }
552    }
553}
554
555impl glib::value::ValueType for IntRange<i64> {
556    type Type = Self;
557}
558
559unsafe impl<'a> glib::value::FromValue<'a> for IntRange<i64> {
560    type Checker = glib::value::GenericValueTypeChecker<Self>;
561
562    #[inline]
563    unsafe fn from_value(value: &'a glib::Value) -> Self {
564        skip_assert_initialized!();
565        let min = ffi::gst_value_get_int64_range_min(value.to_glib_none().0);
566        let max = ffi::gst_value_get_int64_range_max(value.to_glib_none().0);
567        let step = ffi::gst_value_get_int64_range_step(value.to_glib_none().0);
568
569        Self::with_step(min, max, step)
570    }
571}
572
573impl glib::value::ToValue for IntRange<i64> {
574    #[inline]
575    fn to_value(&self) -> glib::Value {
576        let mut value = glib::Value::for_value_type::<Self>();
577        unsafe {
578            ffi::gst_value_set_int64_range_step(
579                value.to_glib_none_mut().0,
580                self.min(),
581                self.max(),
582                self.step(),
583            );
584        }
585        value
586    }
587
588    #[inline]
589    fn value_type(&self) -> glib::Type {
590        Self::static_type()
591    }
592}
593
594impl From<IntRange<i64>> for glib::Value {
595    #[inline]
596    fn from(v: IntRange<i64>) -> glib::Value {
597        skip_assert_initialized!();
598        glib::value::ToValue::to_value(&v)
599    }
600}
601
602#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
603#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
604pub struct FractionRange {
605    min: Fraction,
606    max: Fraction,
607}
608
609impl FractionRange {
610    #[inline]
611    pub fn new<T: Into<Fraction>, U: Into<Fraction>>(min: T, max: U) -> Self {
612        skip_assert_initialized!();
613
614        let min = min.into();
615        let max = max.into();
616
617        assert!(min <= max);
618
619        FractionRange { min, max }
620    }
621
622    #[inline]
623    pub fn min(&self) -> Fraction {
624        self.min
625    }
626
627    #[inline]
628    pub fn max(&self) -> Fraction {
629        self.max
630    }
631}
632
633impl From<(Fraction, Fraction)> for FractionRange {
634    #[inline]
635    fn from((min, max): (Fraction, Fraction)) -> Self {
636        skip_assert_initialized!();
637
638        Self::new(min, max)
639    }
640}
641
642impl glib::types::StaticType for FractionRange {
643    #[inline]
644    fn static_type() -> glib::types::Type {
645        unsafe { from_glib(ffi::gst_fraction_range_get_type()) }
646    }
647}
648
649impl glib::value::ValueType for FractionRange {
650    type Type = Self;
651}
652
653unsafe impl<'a> glib::value::FromValue<'a> for FractionRange {
654    type Checker = glib::value::GenericValueTypeChecker<Self>;
655
656    #[inline]
657    unsafe fn from_value(value: &'a glib::Value) -> Self {
658        skip_assert_initialized!();
659        let min = ffi::gst_value_get_fraction_range_min(value.to_glib_none().0);
660        let max = ffi::gst_value_get_fraction_range_max(value.to_glib_none().0);
661
662        let min_n = ffi::gst_value_get_fraction_numerator(min);
663        let min_d = ffi::gst_value_get_fraction_denominator(min);
664        let max_n = ffi::gst_value_get_fraction_numerator(max);
665        let max_d = ffi::gst_value_get_fraction_denominator(max);
666
667        Self::new((min_n, min_d), (max_n, max_d))
668    }
669}
670
671impl glib::value::ToValue for FractionRange {
672    #[inline]
673    fn to_value(&self) -> glib::Value {
674        let mut value = glib::Value::for_value_type::<Self>();
675        unsafe {
676            ffi::gst_value_set_fraction_range_full(
677                value.to_glib_none_mut().0,
678                self.min().numer(),
679                self.min().denom(),
680                self.max().numer(),
681                self.max().denom(),
682            );
683        }
684        value
685    }
686
687    #[inline]
688    fn value_type(&self) -> glib::Type {
689        Self::static_type()
690    }
691}
692
693impl From<FractionRange> for glib::Value {
694    #[inline]
695    fn from(v: FractionRange) -> glib::Value {
696        skip_assert_initialized!();
697        glib::value::ToValue::to_value(&v)
698    }
699}
700
701#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
702#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
703pub struct Bitmask(pub u64);
704
705impl Bitmask {
706    #[inline]
707    pub fn new(v: u64) -> Self {
708        skip_assert_initialized!();
709        Bitmask(v)
710    }
711}
712
713impl ops::Deref for Bitmask {
714    type Target = u64;
715
716    #[inline]
717    fn deref(&self) -> &u64 {
718        &self.0
719    }
720}
721
722impl ops::DerefMut for Bitmask {
723    #[inline]
724    fn deref_mut(&mut self) -> &mut u64 {
725        &mut self.0
726    }
727}
728
729impl ops::BitAnd for Bitmask {
730    type Output = Self;
731
732    #[inline]
733    fn bitand(self, rhs: Self) -> Self {
734        Bitmask(self.0.bitand(rhs.0))
735    }
736}
737
738impl ops::BitOr for Bitmask {
739    type Output = Self;
740
741    #[inline]
742    fn bitor(self, rhs: Self) -> Self {
743        Bitmask(self.0.bitor(rhs.0))
744    }
745}
746
747impl ops::BitXor for Bitmask {
748    type Output = Self;
749
750    #[inline]
751    fn bitxor(self, rhs: Self) -> Self {
752        Bitmask(self.0.bitxor(rhs.0))
753    }
754}
755
756impl ops::Not for Bitmask {
757    type Output = Self;
758
759    #[inline]
760    fn not(self) -> Self {
761        Bitmask(self.0.not())
762    }
763}
764
765impl From<u64> for Bitmask {
766    #[inline]
767    fn from(v: u64) -> Self {
768        skip_assert_initialized!();
769        Self::new(v)
770    }
771}
772
773impl glib::types::StaticType for Bitmask {
774    #[inline]
775    fn static_type() -> glib::types::Type {
776        unsafe { from_glib(ffi::gst_bitmask_get_type()) }
777    }
778}
779
780impl glib::value::ValueType for Bitmask {
781    type Type = Self;
782}
783
784unsafe impl<'a> glib::value::FromValue<'a> for Bitmask {
785    type Checker = glib::value::GenericValueTypeChecker<Self>;
786
787    #[inline]
788    unsafe fn from_value(value: &'a glib::Value) -> Self {
789        skip_assert_initialized!();
790        let v = ffi::gst_value_get_bitmask(value.to_glib_none().0);
791        Self::new(v)
792    }
793}
794
795impl glib::value::ToValue for Bitmask {
796    #[inline]
797    fn to_value(&self) -> glib::Value {
798        let mut value = glib::Value::for_value_type::<Self>();
799        unsafe {
800            ffi::gst_value_set_bitmask(value.to_glib_none_mut().0, self.0);
801        }
802        value
803    }
804
805    #[inline]
806    fn value_type(&self) -> glib::Type {
807        Self::static_type()
808    }
809}
810
811impl From<Bitmask> for glib::Value {
812    #[inline]
813    fn from(v: Bitmask) -> glib::Value {
814        skip_assert_initialized!();
815        glib::value::ToValue::to_value(&v)
816    }
817}
818
819#[derive(Clone)]
820pub struct Array(glib::SendValue);
821
822unsafe impl Send for Array {}
823unsafe impl Sync for Array {}
824
825impl fmt::Debug for Array {
826    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
827        f.debug_tuple("Array").field(&self.as_slice()).finish()
828    }
829}
830
831impl Array {
832    pub fn new(values: impl IntoIterator<Item = impl Into<glib::Value> + Send>) -> Self {
833        assert_initialized_main_thread!();
834
835        unsafe {
836            let mut value = glib::Value::for_value_type::<Array>();
837            for v in values.into_iter() {
838                let mut v = v.into().into_raw();
839                ffi::gst_value_array_append_and_take_value(value.to_glib_none_mut().0, &mut v);
840            }
841
842            Self(glib::SendValue::unsafe_from(value.into_raw()))
843        }
844    }
845
846    pub fn from_values(values: impl IntoIterator<Item = glib::SendValue>) -> Self {
847        skip_assert_initialized!();
848
849        Self::new(values)
850    }
851
852    #[inline]
853    pub fn as_slice(&self) -> &[glib::SendValue] {
854        unsafe {
855            let arr = (*self.0.as_ptr()).data[0].v_pointer as *const glib::ffi::GArray;
856            if arr.is_null() || (*arr).len == 0 {
857                &[]
858            } else {
859                #[allow(clippy::cast_ptr_alignment)]
860                slice::from_raw_parts((*arr).data as *const glib::SendValue, (*arr).len as usize)
861            }
862        }
863    }
864
865    pub fn append_value(&mut self, value: glib::SendValue) {
866        unsafe {
867            ffi::gst_value_array_append_and_take_value(
868                self.0.to_glib_none_mut().0,
869                &mut value.into_raw(),
870            );
871        }
872    }
873
874    pub fn append(&mut self, value: impl Into<glib::Value> + Send) {
875        self.append_value(glib::SendValue::from_owned(value));
876    }
877}
878
879impl Default for Array {
880    fn default() -> Self {
881        skip_assert_initialized!();
882
883        unsafe {
884            let value = glib::Value::for_value_type::<Array>();
885
886            Self(glib::SendValue::unsafe_from(value.into_raw()))
887        }
888    }
889}
890
891impl ops::Deref for Array {
892    type Target = [glib::SendValue];
893
894    #[inline]
895    fn deref(&self) -> &[glib::SendValue] {
896        self.as_slice()
897    }
898}
899
900impl AsRef<[glib::SendValue]> for Array {
901    #[inline]
902    fn as_ref(&self) -> &[glib::SendValue] {
903        self.as_slice()
904    }
905}
906
907impl std::iter::FromIterator<glib::SendValue> for Array {
908    fn from_iter<T: IntoIterator<Item = glib::SendValue>>(iter: T) -> Self {
909        skip_assert_initialized!();
910        Self::from_values(iter)
911    }
912}
913
914impl std::iter::Extend<glib::SendValue> for Array {
915    fn extend<T: IntoIterator<Item = glib::SendValue>>(&mut self, iter: T) {
916        for v in iter.into_iter() {
917            self.append_value(v);
918        }
919    }
920}
921
922impl glib::value::ValueType for Array {
923    type Type = Self;
924}
925
926unsafe impl<'a> glib::value::FromValue<'a> for Array {
927    type Checker = glib::value::GenericValueTypeChecker<Self>;
928
929    unsafe fn from_value(value: &'a glib::Value) -> Self {
930        skip_assert_initialized!();
931        Self(glib::SendValue::unsafe_from(value.clone().into_raw()))
932    }
933}
934
935impl glib::value::ToValue for Array {
936    fn to_value(&self) -> glib::Value {
937        self.0.clone().into()
938    }
939
940    fn value_type(&self) -> glib::Type {
941        Self::static_type()
942    }
943}
944
945impl From<Array> for glib::Value {
946    fn from(v: Array) -> glib::Value {
947        skip_assert_initialized!();
948        v.0.into()
949    }
950}
951
952impl glib::types::StaticType for Array {
953    #[inline]
954    fn static_type() -> glib::types::Type {
955        unsafe { from_glib(ffi::gst_value_array_get_type()) }
956    }
957}
958
959#[derive(Debug, Clone)]
960pub struct ArrayRef<'a>(&'a [glib::SendValue]);
961
962unsafe impl Send for ArrayRef<'_> {}
963unsafe impl Sync for ArrayRef<'_> {}
964
965impl<'a> ArrayRef<'a> {
966    pub fn new(values: &'a [glib::SendValue]) -> Self {
967        skip_assert_initialized!();
968
969        Self(values)
970    }
971
972    #[inline]
973    pub fn as_slice(&self) -> &'a [glib::SendValue] {
974        self.0
975    }
976}
977
978impl ops::Deref for ArrayRef<'_> {
979    type Target = [glib::SendValue];
980
981    #[inline]
982    fn deref(&self) -> &[glib::SendValue] {
983        self.as_slice()
984    }
985}
986
987impl AsRef<[glib::SendValue]> for ArrayRef<'_> {
988    #[inline]
989    fn as_ref(&self) -> &[glib::SendValue] {
990        self.as_slice()
991    }
992}
993
994unsafe impl<'a> glib::value::FromValue<'a> for ArrayRef<'a> {
995    type Checker = glib::value::GenericValueTypeChecker<Self>;
996
997    #[inline]
998    unsafe fn from_value(value: &'a glib::Value) -> Self {
999        skip_assert_initialized!();
1000        let arr = (*value.as_ptr()).data[0].v_pointer as *const glib::ffi::GArray;
1001        if arr.is_null() || (*arr).len == 0 {
1002            Self(&[])
1003        } else {
1004            #[allow(clippy::cast_ptr_alignment)]
1005            Self(slice::from_raw_parts(
1006                (*arr).data as *const glib::SendValue,
1007                (*arr).len as usize,
1008            ))
1009        }
1010    }
1011}
1012
1013impl glib::value::ToValue for ArrayRef<'_> {
1014    #[inline]
1015    fn to_value(&self) -> glib::Value {
1016        let mut value = glib::Value::for_value_type::<Array>();
1017        unsafe {
1018            for v in self.0 {
1019                ffi::gst_value_array_append_value(value.to_glib_none_mut().0, v.to_glib_none().0);
1020            }
1021        }
1022        value
1023    }
1024
1025    #[inline]
1026    fn value_type(&self) -> glib::Type {
1027        Self::static_type()
1028    }
1029}
1030
1031impl<'a> From<ArrayRef<'a>> for glib::Value {
1032    #[inline]
1033    fn from(v: ArrayRef<'a>) -> glib::Value {
1034        skip_assert_initialized!();
1035        glib::value::ToValue::to_value(&v)
1036    }
1037}
1038
1039impl glib::types::StaticType for ArrayRef<'_> {
1040    #[inline]
1041    fn static_type() -> glib::types::Type {
1042        unsafe { from_glib(ffi::gst_value_array_get_type()) }
1043    }
1044}
1045
1046#[derive(Clone)]
1047pub struct List(glib::SendValue);
1048
1049unsafe impl Send for List {}
1050unsafe impl Sync for List {}
1051
1052impl fmt::Debug for List {
1053    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1054        f.debug_tuple("List").field(&self.as_slice()).finish()
1055    }
1056}
1057
1058impl List {
1059    pub fn new(values: impl IntoIterator<Item = impl Into<glib::Value> + Send>) -> Self {
1060        assert_initialized_main_thread!();
1061
1062        unsafe {
1063            let mut value = glib::Value::for_value_type::<List>();
1064            for v in values.into_iter() {
1065                let mut v = v.into().into_raw();
1066                ffi::gst_value_list_append_and_take_value(value.to_glib_none_mut().0, &mut v);
1067            }
1068
1069            Self(glib::SendValue::unsafe_from(value.into_raw()))
1070        }
1071    }
1072
1073    pub fn from_values(values: impl IntoIterator<Item = glib::SendValue>) -> Self {
1074        skip_assert_initialized!();
1075
1076        Self::new(values)
1077    }
1078
1079    #[inline]
1080    pub fn as_slice(&self) -> &[glib::SendValue] {
1081        unsafe {
1082            let arr = (*self.0.as_ptr()).data[0].v_pointer as *const glib::ffi::GArray;
1083            if arr.is_null() || (*arr).len == 0 {
1084                &[]
1085            } else {
1086                #[allow(clippy::cast_ptr_alignment)]
1087                slice::from_raw_parts((*arr).data as *const glib::SendValue, (*arr).len as usize)
1088            }
1089        }
1090    }
1091
1092    pub fn append_value(&mut self, value: glib::SendValue) {
1093        unsafe {
1094            ffi::gst_value_list_append_and_take_value(
1095                self.0.to_glib_none_mut().0,
1096                &mut value.into_raw(),
1097            );
1098        }
1099    }
1100
1101    pub fn append(&mut self, value: impl Into<glib::Value> + Send) {
1102        self.append_value(glib::SendValue::from_owned(value));
1103    }
1104}
1105
1106impl Default for List {
1107    fn default() -> Self {
1108        skip_assert_initialized!();
1109
1110        unsafe {
1111            let value = glib::Value::for_value_type::<List>();
1112
1113            Self(glib::SendValue::unsafe_from(value.into_raw()))
1114        }
1115    }
1116}
1117
1118impl ops::Deref for List {
1119    type Target = [glib::SendValue];
1120
1121    #[inline]
1122    fn deref(&self) -> &[glib::SendValue] {
1123        self.as_slice()
1124    }
1125}
1126
1127impl AsRef<[glib::SendValue]> for List {
1128    #[inline]
1129    fn as_ref(&self) -> &[glib::SendValue] {
1130        self.as_slice()
1131    }
1132}
1133
1134impl std::iter::FromIterator<glib::SendValue> for List {
1135    fn from_iter<T: IntoIterator<Item = glib::SendValue>>(iter: T) -> Self {
1136        skip_assert_initialized!();
1137        Self::from_values(iter)
1138    }
1139}
1140
1141impl std::iter::Extend<glib::SendValue> for List {
1142    fn extend<T: IntoIterator<Item = glib::SendValue>>(&mut self, iter: T) {
1143        for v in iter.into_iter() {
1144            self.append_value(v);
1145        }
1146    }
1147}
1148
1149impl glib::value::ValueType for List {
1150    type Type = Self;
1151}
1152
1153unsafe impl<'a> glib::value::FromValue<'a> for List {
1154    type Checker = glib::value::GenericValueTypeChecker<Self>;
1155
1156    unsafe fn from_value(value: &'a glib::Value) -> Self {
1157        skip_assert_initialized!();
1158        Self(glib::SendValue::unsafe_from(value.clone().into_raw()))
1159    }
1160}
1161
1162impl glib::value::ToValue for List {
1163    fn to_value(&self) -> glib::Value {
1164        self.0.clone().into()
1165    }
1166
1167    fn value_type(&self) -> glib::Type {
1168        Self::static_type()
1169    }
1170}
1171
1172impl From<List> for glib::Value {
1173    fn from(v: List) -> glib::Value {
1174        skip_assert_initialized!();
1175        v.0.into()
1176    }
1177}
1178
1179impl glib::types::StaticType for List {
1180    #[inline]
1181    fn static_type() -> glib::types::Type {
1182        unsafe { from_glib(ffi::gst_value_list_get_type()) }
1183    }
1184}
1185
1186#[derive(Debug, Clone)]
1187pub struct ListRef<'a>(&'a [glib::SendValue]);
1188
1189unsafe impl Send for ListRef<'_> {}
1190unsafe impl Sync for ListRef<'_> {}
1191
1192impl<'a> ListRef<'a> {
1193    pub fn new(values: &'a [glib::SendValue]) -> Self {
1194        skip_assert_initialized!();
1195
1196        Self(values)
1197    }
1198
1199    #[inline]
1200    pub fn as_slice(&self) -> &'a [glib::SendValue] {
1201        self.0
1202    }
1203}
1204
1205impl ops::Deref for ListRef<'_> {
1206    type Target = [glib::SendValue];
1207
1208    #[inline]
1209    fn deref(&self) -> &[glib::SendValue] {
1210        self.as_slice()
1211    }
1212}
1213
1214impl AsRef<[glib::SendValue]> for ListRef<'_> {
1215    #[inline]
1216    fn as_ref(&self) -> &[glib::SendValue] {
1217        self.as_slice()
1218    }
1219}
1220
1221unsafe impl<'a> glib::value::FromValue<'a> for ListRef<'a> {
1222    type Checker = glib::value::GenericValueTypeChecker<Self>;
1223
1224    #[inline]
1225    unsafe fn from_value(value: &'a glib::Value) -> Self {
1226        skip_assert_initialized!();
1227        let arr = (*value.as_ptr()).data[0].v_pointer as *const glib::ffi::GArray;
1228        if arr.is_null() || (*arr).len == 0 {
1229            Self(&[])
1230        } else {
1231            #[allow(clippy::cast_ptr_alignment)]
1232            Self(slice::from_raw_parts(
1233                (*arr).data as *const glib::SendValue,
1234                (*arr).len as usize,
1235            ))
1236        }
1237    }
1238}
1239
1240impl glib::value::ToValue for ListRef<'_> {
1241    #[inline]
1242    fn to_value(&self) -> glib::Value {
1243        let mut value = glib::Value::for_value_type::<List>();
1244        unsafe {
1245            for v in self.0 {
1246                ffi::gst_value_list_append_value(value.to_glib_none_mut().0, v.to_glib_none().0);
1247            }
1248        }
1249        value
1250    }
1251
1252    #[inline]
1253    fn value_type(&self) -> glib::Type {
1254        Self::static_type()
1255    }
1256}
1257
1258impl<'a> From<ListRef<'a>> for glib::Value {
1259    #[inline]
1260    fn from(v: ListRef<'a>) -> glib::Value {
1261        skip_assert_initialized!();
1262        glib::value::ToValue::to_value(&v)
1263    }
1264}
1265
1266impl glib::types::StaticType for ListRef<'_> {
1267    #[inline]
1268    fn static_type() -> glib::types::Type {
1269        unsafe { from_glib(ffi::gst_value_list_get_type()) }
1270    }
1271}
1272
1273pub trait GstValueExt: Sized {
1274    #[doc(alias = "gst_value_can_compare")]
1275    fn can_compare(&self, other: &Self) -> bool;
1276    #[doc(alias = "gst_value_compare")]
1277    fn compare(&self, other: &Self) -> Option<cmp::Ordering>;
1278    fn eq(&self, other: &Self) -> bool;
1279    #[doc(alias = "gst_value_can_intersect")]
1280    fn can_intersect(&self, other: &Self) -> bool;
1281    #[doc(alias = "gst_value_intersect")]
1282    fn intersect(&self, other: &Self) -> Option<Self>;
1283    #[doc(alias = "gst_value_can_subtract")]
1284    fn can_subtract(&self, other: &Self) -> bool;
1285    #[doc(alias = "gst_value_subtract")]
1286    fn subtract(&self, other: &Self) -> Option<Self>;
1287    #[doc(alias = "gst_value_can_union")]
1288    fn can_union(&self, other: &Self) -> bool;
1289    #[doc(alias = "gst_value_union")]
1290    fn union(&self, other: &Self) -> Option<Self>;
1291    #[doc(alias = "gst_value_fixate")]
1292    fn fixate(&self) -> Option<Self>;
1293    #[doc(alias = "gst_value_is_fixed")]
1294    fn is_fixed(&self) -> bool;
1295    #[doc(alias = "gst_value_is_subset")]
1296    fn is_subset(&self, superset: &Self) -> bool;
1297    #[doc(alias = "gst_value_serialize")]
1298    fn serialize(&self) -> Result<glib::GString, glib::BoolError>;
1299    #[doc(alias = "gst_value_deserialize")]
1300    fn deserialize(s: &str, type_: glib::Type) -> Result<glib::Value, glib::BoolError>;
1301    #[cfg(feature = "v1_20")]
1302    #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
1303    #[doc(alias = "gst_value_deserialize_with_pspec")]
1304    fn deserialize_with_pspec(
1305        s: &str,
1306        pspec: &glib::ParamSpec,
1307    ) -> Result<glib::Value, glib::BoolError>;
1308}
1309
1310impl GstValueExt for glib::Value {
1311    fn can_compare(&self, other: &Self) -> bool {
1312        unsafe {
1313            from_glib(ffi::gst_value_can_compare(
1314                self.to_glib_none().0,
1315                other.to_glib_none().0,
1316            ))
1317        }
1318    }
1319
1320    fn compare(&self, other: &Self) -> Option<cmp::Ordering> {
1321        unsafe {
1322            let val = ffi::gst_value_compare(self.to_glib_none().0, other.to_glib_none().0);
1323
1324            match val {
1325                ffi::GST_VALUE_LESS_THAN => Some(cmp::Ordering::Less),
1326                ffi::GST_VALUE_EQUAL => Some(cmp::Ordering::Equal),
1327                ffi::GST_VALUE_GREATER_THAN => Some(cmp::Ordering::Greater),
1328                _ => None,
1329            }
1330        }
1331    }
1332
1333    fn eq(&self, other: &Self) -> bool {
1334        self.compare(other) == Some(cmp::Ordering::Equal)
1335    }
1336
1337    fn can_intersect(&self, other: &Self) -> bool {
1338        unsafe {
1339            from_glib(ffi::gst_value_can_intersect(
1340                self.to_glib_none().0,
1341                other.to_glib_none().0,
1342            ))
1343        }
1344    }
1345
1346    fn intersect(&self, other: &Self) -> Option<Self> {
1347        unsafe {
1348            let mut value = glib::Value::uninitialized();
1349            let ret: bool = from_glib(ffi::gst_value_intersect(
1350                value.to_glib_none_mut().0,
1351                self.to_glib_none().0,
1352                other.to_glib_none().0,
1353            ));
1354            if ret {
1355                Some(value)
1356            } else {
1357                None
1358            }
1359        }
1360    }
1361
1362    fn can_subtract(&self, other: &Self) -> bool {
1363        unsafe {
1364            from_glib(ffi::gst_value_can_subtract(
1365                self.to_glib_none().0,
1366                other.to_glib_none().0,
1367            ))
1368        }
1369    }
1370
1371    fn subtract(&self, other: &Self) -> Option<Self> {
1372        unsafe {
1373            let mut value = glib::Value::uninitialized();
1374            let ret: bool = from_glib(ffi::gst_value_subtract(
1375                value.to_glib_none_mut().0,
1376                self.to_glib_none().0,
1377                other.to_glib_none().0,
1378            ));
1379            if ret {
1380                Some(value)
1381            } else {
1382                None
1383            }
1384        }
1385    }
1386
1387    fn can_union(&self, other: &Self) -> bool {
1388        unsafe {
1389            from_glib(ffi::gst_value_can_union(
1390                self.to_glib_none().0,
1391                other.to_glib_none().0,
1392            ))
1393        }
1394    }
1395
1396    fn union(&self, other: &Self) -> Option<Self> {
1397        unsafe {
1398            let mut value = glib::Value::uninitialized();
1399            let ret: bool = from_glib(ffi::gst_value_union(
1400                value.to_glib_none_mut().0,
1401                self.to_glib_none().0,
1402                other.to_glib_none().0,
1403            ));
1404            if ret {
1405                Some(value)
1406            } else {
1407                None
1408            }
1409        }
1410    }
1411
1412    fn fixate(&self) -> Option<Self> {
1413        unsafe {
1414            let mut value = glib::Value::uninitialized();
1415            let ret: bool = from_glib(ffi::gst_value_fixate(
1416                value.to_glib_none_mut().0,
1417                self.to_glib_none().0,
1418            ));
1419            if ret {
1420                Some(value)
1421            } else {
1422                None
1423            }
1424        }
1425    }
1426
1427    fn is_fixed(&self) -> bool {
1428        unsafe { from_glib(ffi::gst_value_is_fixed(self.to_glib_none().0)) }
1429    }
1430
1431    fn is_subset(&self, superset: &Self) -> bool {
1432        unsafe {
1433            from_glib(ffi::gst_value_is_subset(
1434                self.to_glib_none().0,
1435                superset.to_glib_none().0,
1436            ))
1437        }
1438    }
1439
1440    fn serialize(&self) -> Result<glib::GString, glib::BoolError> {
1441        unsafe {
1442            Option::<_>::from_glib_full(ffi::gst_value_serialize(self.to_glib_none().0))
1443                .ok_or_else(|| glib::bool_error!("Failed to serialize value"))
1444        }
1445    }
1446
1447    fn deserialize(s: &str, type_: glib::Type) -> Result<glib::Value, glib::BoolError> {
1448        skip_assert_initialized!();
1449
1450        unsafe {
1451            let mut value = glib::Value::from_type(type_);
1452            let ret: bool = from_glib(ffi::gst_value_deserialize(
1453                value.to_glib_none_mut().0,
1454                s.to_glib_none().0,
1455            ));
1456            if ret {
1457                Ok(value)
1458            } else {
1459                Err(glib::bool_error!("Failed to deserialize value"))
1460            }
1461        }
1462    }
1463
1464    #[cfg(feature = "v1_20")]
1465    #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
1466    fn deserialize_with_pspec(
1467        s: &str,
1468        pspec: &glib::ParamSpec,
1469    ) -> Result<glib::Value, glib::BoolError> {
1470        skip_assert_initialized!();
1471
1472        unsafe {
1473            let mut value = glib::Value::from_type_unchecked(pspec.value_type());
1474            let ret: bool = from_glib(ffi::gst_value_deserialize_with_pspec(
1475                value.to_glib_none_mut().0,
1476                s.to_glib_none().0,
1477                pspec.to_glib_none().0,
1478            ));
1479            if ret {
1480                Ok(value)
1481            } else {
1482                Err(glib::bool_error!("Failed to deserialize value"))
1483            }
1484        }
1485    }
1486}
1487
1488#[doc(hidden)]
1489#[macro_export]
1490macro_rules! impl_builder_gvalue_extra_setters (
1491    (field) => {
1492        // rustdoc-stripper-ignore-next
1493        /// Sets field `name` to the given inner value if the `predicate` evaluates to `true`.
1494        ///
1495        /// This has no effect if the `predicate` evaluates to `false`,
1496        /// i.e. default or previous value for `name` is kept.
1497        #[inline]
1498        pub fn field_if(self, name: impl $crate::glib::IntoGStr, value: impl Into<$crate::glib::Value> + Send, predicate: bool) -> Self {
1499            if predicate {
1500                self.field(name, value)
1501            } else {
1502                self
1503            }
1504        }
1505
1506        // rustdoc-stripper-ignore-next
1507        /// Sets field `name` to the given inner value if `value` is `Some`.
1508        ///
1509        /// This has no effect if the value is `None`, i.e. default or previous value for `name` is kept.
1510        #[inline]
1511        pub fn field_if_some(self, name: impl $crate::glib::IntoGStr, value: Option<impl Into<$crate::glib::Value> + Send>) -> Self {
1512            if let Some(value) = value {
1513                self.field(name, value)
1514            } else {
1515                self
1516            }
1517        }
1518
1519        // rustdoc-stripper-ignore-next
1520        /// Sets field `name` using the given `ValueType` `V` built from `iter`'s the `Item`s.
1521        ///
1522        /// Overrides any default or previously defined value for `name`.
1523        #[inline]
1524        pub fn field_from_iter<V: $crate::glib::value::ValueType + Into<$crate::glib::Value> + FromIterator<$crate::glib::SendValue> + Send>(
1525            self,
1526            name: impl $crate::glib::IntoGStr,
1527            iter: impl IntoIterator<Item = impl $crate::glib::value::ToSendValue>,
1528        ) -> Self {
1529            let iter = iter.into_iter().map(|item| item.to_send_value());
1530            self.field(name, V::from_iter(iter))
1531        }
1532
1533        // rustdoc-stripper-ignore-next
1534        /// Sets field `name` using the given `ValueType` `V` built from `iter`'s Item`s,
1535        /// if `iter` is not empty.
1536        ///
1537        /// This has no effect if `iter` is empty, i.e. previous value for `name` is unchanged.
1538        #[inline]
1539        pub fn field_if_not_empty<V: $crate::glib::value::ValueType + Into<$crate::glib::Value> + FromIterator<$crate::glib::SendValue> + Send>(
1540            self,
1541            name: impl $crate::glib::IntoGStr,
1542            iter: impl IntoIterator<Item = impl $crate::glib::value::ToSendValue>,
1543        ) -> Self {
1544            let mut iter = iter.into_iter().peekable();
1545            if iter.peek().is_some() {
1546                let iter = iter.map(|item| item.to_send_value());
1547                self.field(name, V::from_iter(iter))
1548            } else {
1549                self
1550            }
1551        }
1552    };
1553
1554    (other_field) => {
1555        // rustdoc-stripper-ignore-next
1556        /// Sets field `name` to the given inner value if the `predicate` evaluates to `true`.
1557        ///
1558        /// This has no effect if the `predicate` evaluates to `false`,
1559        /// i.e. default or previous value for `name` is kept.
1560        #[inline]
1561        pub fn other_field_if(self, name: &'a str, value: impl $crate::glib::value::ToSendValue, predicate: bool) -> Self {
1562            if predicate {
1563                self.other_field(name, value)
1564            } else {
1565                self
1566            }
1567        }
1568
1569        // rustdoc-stripper-ignore-next
1570        /// Sets field `name` to the given inner value if `value` is `Some`.
1571        ///
1572        /// This has no effect if the value is `None`, i.e. default or previous value for `name` is kept.
1573        #[inline]
1574        pub fn other_field_if_some(self, name: &'a str, value: Option<impl $crate::glib::value::ToSendValue>) -> Self {
1575            if let Some(value) = value {
1576                self.other_field(name, value)
1577            } else {
1578                self
1579            }
1580        }
1581
1582        // rustdoc-stripper-ignore-next
1583        /// Sets field `name` using the given `ValueType` `V` built from `iter`'s the `Item`s.
1584        ///
1585        /// Overrides any default or previously defined value for `name`.
1586        #[inline]
1587        pub fn other_field_from_iter<V: $crate::glib::value::ValueType + $crate::glib::value::ToSendValue + FromIterator<$crate::glib::SendValue>>(
1588            self,
1589            name: &'a str,
1590            iter: impl IntoIterator<Item = impl $crate::glib::value::ToSendValue>,
1591        ) -> Self {
1592            let iter = iter.into_iter().map(|item| item.to_send_value());
1593            self.other_field(name, V::from_iter(iter))
1594        }
1595
1596        // rustdoc-stripper-ignore-next
1597        /// Sets field `name` using the given `ValueType` `V` built from `iter`'s Item`s,
1598        /// if `iter` is not empty.
1599        ///
1600        /// This has no effect if `iter` is empty, i.e. previous value for `name` is unchanged.
1601        #[inline]
1602        pub fn other_field_if_not_empty<V: $crate::glib::value::ValueType + $crate::glib::value::ToSendValue + FromIterator<$crate::glib::SendValue>>(
1603            self,
1604            name: &'a str,
1605            iter: impl IntoIterator<Item = impl $crate::glib::value::ToSendValue>,
1606        ) -> Self {
1607            let mut iter = iter.into_iter().peekable();
1608            if iter.peek().is_some() {
1609                let iter = iter.map(|item| item.to_send_value());
1610                self.other_field(name, V::from_iter(iter))
1611            } else {
1612                self
1613            }
1614        }
1615     };
1616
1617    (property) => {
1618        // rustdoc-stripper-ignore-next
1619        /// Sets property `name` to the given inner value if the `predicate` evaluates to `true`.
1620        ///
1621        /// This has no effect if the `predicate` evaluates to `false`,
1622        /// i.e. default or previous value for `name` is kept.
1623        #[inline]
1624        pub fn property_if(self, name: &'a str, value: impl Into<$crate::glib::Value> + 'a, predicate: bool) -> Self {
1625            if predicate {
1626                self.property(name, value)
1627            } else {
1628                self
1629            }
1630        }
1631
1632        // rustdoc-stripper-ignore-next
1633        /// Sets property `name` to the given inner value if `value` is `Some`.
1634        ///
1635        /// This has no effect if the value is `None`, i.e. default or previous value for `name` is kept.
1636        #[inline]
1637        pub fn property_if_some(self, name: &'a str, value: Option<impl Into<$crate::glib::Value> + 'a>) -> Self {
1638            if let Some(value) = value {
1639                self.property(name, value)
1640            } else {
1641                self
1642            }
1643        }
1644
1645        // rustdoc-stripper-ignore-next
1646        /// Sets property `name` using the given `ValueType` `V` built from `iter`'s the `Item`s.
1647        ///
1648        /// Overrides any default or previously defined value for `name`.
1649        #[inline]
1650        pub fn property_from_iter<V: $crate::glib::value::ValueType + Into<$crate::glib::Value> + FromIterator<$crate::glib::SendValue>>(
1651            self,
1652            name: &'a str,
1653            iter: impl IntoIterator<Item = impl $crate::glib::value::ToSendValue>,
1654        ) -> Self {
1655            let iter = iter.into_iter().map(|item| item.to_send_value());
1656            self.property(name, V::from_iter(iter))
1657        }
1658
1659        // rustdoc-stripper-ignore-next
1660        /// Sets property `name` using the given `ValueType` `V` built from `iter`'s Item`s,
1661        /// if `iter` is not empty.
1662        ///
1663        /// This has no effect if `iter` is empty, i.e. previous value for `name` is unchanged.
1664        #[inline]
1665        pub fn property_if_not_empty<V: $crate::glib::value::ValueType + Into<$crate::glib::Value> + FromIterator<$crate::glib::SendValue>>(
1666            self,
1667            name: &'a str,
1668            iter: impl IntoIterator<Item = impl $crate::glib::value::ToSendValue>,
1669        ) -> Self {
1670            let mut iter = iter.into_iter().peekable();
1671            if iter.peek().is_some() {
1672                let iter = iter.map(|item| item.to_send_value());
1673                self.property(name, V::from_iter(iter))
1674            } else {
1675                self
1676            }
1677        }
1678     };
1679);
1680
1681#[cfg(test)]
1682mod tests {
1683    use super::*;
1684
1685    #[test]
1686    fn test_fraction() {
1687        crate::init().unwrap();
1688
1689        let f1 = crate::Fraction::new(1, 2);
1690        let f2 = crate::Fraction::new(2, 3);
1691        let mut f3 = f1 * f2;
1692        let f4 = f1 * f2;
1693        f3 *= f2;
1694        f3 *= f4;
1695
1696        assert_eq!(f3, crate::Fraction::new(2, 27));
1697    }
1698
1699    #[test]
1700    fn test_int_range_constructor() {
1701        crate::init().unwrap();
1702
1703        // Type inference should figure out the type
1704        let _r1 = crate::IntRange::new(1i32, 2i32);
1705        let _r2 = crate::IntRange::with_step(2i64, 10i64, 2i64);
1706        let _r3 = crate::IntRange::with_step(0i64, 6i64, 3i64);
1707    }
1708
1709    #[test]
1710    #[should_panic(expected = "step size must be greater than zero")]
1711    fn test_int_range_constructor_step0() {
1712        crate::init().unwrap();
1713        let _r = crate::IntRange::with_step(0i32, 2i32, 0i32);
1714    }
1715
1716    #[test]
1717    #[should_panic(expected = "maximum value must be greater than minimum value")]
1718    fn test_int_range_constructor_max_min() {
1719        crate::init().unwrap();
1720        let _r = crate::IntRange::with_step(4i32, 2i32, 2i32);
1721    }
1722
1723    #[test]
1724    #[should_panic(expected = "maximum value must be greater than minimum value")]
1725    fn test_int_range_constructor_max_eq_min() {
1726        crate::init().unwrap();
1727        let _r = crate::IntRange::with_step(4i32, 4i32, 2i32);
1728    }
1729
1730    #[test]
1731    #[should_panic(expected = "minimum value must be evenly dividable by step size")]
1732    fn test_int_range_constructor_bad_step() {
1733        crate::init().unwrap();
1734        let _r = crate::IntRange::with_step(1i32, 10i32, 2i32);
1735    }
1736
1737    #[test]
1738    #[should_panic(expected = "maximum value must be evenly dividable by step size")]
1739    fn test_int_range_constructor_bad_step_max() {
1740        crate::init().unwrap();
1741        let _r = crate::IntRange::with_step(0i32, 10i32, 3i32);
1742    }
1743
1744    #[test]
1745    #[should_panic(expected = "step size must be greater than zero")]
1746    fn test_int_range_constructor_step0_i64() {
1747        crate::init().unwrap();
1748        let _r = crate::IntRange::with_step(0i64, 2i64, 0i64);
1749    }
1750
1751    #[test]
1752    #[should_panic(expected = "maximum value must be greater than minimum value")]
1753    fn test_int_range_constructor_max_min_i64() {
1754        crate::init().unwrap();
1755        let _r = crate::IntRange::with_step(4i64, 2i64, 2i64);
1756    }
1757
1758    #[test]
1759    #[should_panic(expected = "maximum value must be greater than minimum value")]
1760    fn test_int_range_constructor_max_eq_min_i64() {
1761        crate::init().unwrap();
1762        let _r = crate::IntRange::with_step(4i64, 4i64, 2i64);
1763    }
1764
1765    #[test]
1766    #[should_panic(expected = "minimum value must be evenly dividable by step size")]
1767    fn test_int_range_constructor_bad_step_i64() {
1768        crate::init().unwrap();
1769        let _r = crate::IntRange::with_step(1i64, 10i64, 2i64);
1770    }
1771    #[test]
1772    #[should_panic(expected = "maximum value must be evenly dividable by step size")]
1773    fn test_int_range_constructor_bad_step_max_i64() {
1774        crate::init().unwrap();
1775        let _r = crate::IntRange::with_step(0i64, 10i64, 3i64);
1776    }
1777
1778    #[test]
1779    fn test_deserialize() {
1780        crate::init().unwrap();
1781
1782        let v = glib::Value::deserialize("123", i32::static_type()).unwrap();
1783        assert_eq!(v.get::<i32>(), Ok(123));
1784    }
1785}