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<T: Into<glib::Value> + Send>(values: impl IntoIterator<Item = T>) -> 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<T: Into<glib::Value> + Send>(values: impl IntoIterator<Item = T>) -> 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 the `predicate` evaluates to `true`.
1508        ///
1509        /// This has no effect if the `predicate` evaluates to `false`,
1510        /// i.e. default or previous value for `name` is kept.
1511        #[inline]
1512        pub fn field_with_static_if(self, name: impl AsRef<$crate::glib::GStr> + 'static, value: impl Into<$crate::glib::Value> + Send, predicate: bool) -> Self {
1513            if predicate {
1514                self.field_with_static(name, value)
1515            } else {
1516                self
1517            }
1518        }
1519
1520        // rustdoc-stripper-ignore-next
1521        /// Sets field `name` to the given inner value if the `predicate` evaluates to `true`.
1522        ///
1523        /// This has no effect if the `predicate` evaluates to `false`,
1524        /// i.e. default or previous value for `name` is kept.
1525        #[inline]
1526        pub fn field_with_id_if(self, name: impl AsRef<$crate::IdStr>, value: impl Into<$crate::glib::Value> + Send, predicate: bool) -> Self {
1527            if predicate {
1528                self.field_with_id(name, value)
1529            } else {
1530                self
1531            }
1532        }
1533
1534        // rustdoc-stripper-ignore-next
1535        /// Sets field `name` to the given inner value if `value` is `Some`.
1536        ///
1537        /// This has no effect if the value is `None`, i.e. default or previous value for `name` is kept.
1538        #[inline]
1539        pub fn field_if_some(self, name: impl $crate::glib::IntoGStr, value: Option<impl Into<$crate::glib::Value> + Send>) -> Self {
1540            if let Some(value) = value {
1541                self.field(name, value)
1542            } else {
1543                self
1544            }
1545        }
1546
1547        // rustdoc-stripper-ignore-next
1548        /// Sets field `name` to the given inner value if `value` is `Some`.
1549        ///
1550        /// This has no effect if the value is `None`, i.e. default or previous value for `name` is kept.
1551        #[inline]
1552        pub fn field_with_static_if_some(self, name: impl AsRef<$crate::glib::GStr> + 'static, value: Option<impl Into<$crate::glib::Value> + Send>) -> Self {
1553            if let Some(value) = value {
1554                self.field_with_static(name, value)
1555            } else {
1556                self
1557            }
1558        }
1559
1560        // rustdoc-stripper-ignore-next
1561        /// Sets field `name` to the given inner value if `value` is `Some`.
1562        ///
1563        /// This has no effect if the value is `None`, i.e. default or previous value for `name` is kept.
1564        #[inline]
1565        pub fn field_with_id_if_some(self, name: impl AsRef<$crate::IdStr>, value: Option<impl Into<$crate::glib::Value> + Send>) -> Self {
1566            if let Some(value) = value {
1567                self.field_with_id(name, value)
1568            } else {
1569                self
1570            }
1571        }
1572
1573        // rustdoc-stripper-ignore-next
1574        /// Sets field `name` using the given `ValueType` `V` built from `iter`'s the `Item`s.
1575        ///
1576        /// Overrides any default or previously defined value for `name`.
1577        #[inline]
1578        pub fn field_from_iter<
1579            V: $crate::glib::value::ValueType + Into<$crate::glib::Value> + FromIterator<$crate::glib::SendValue> + Send,
1580            I: $crate::glib::value::ToSendValue,
1581        >(
1582            self,
1583            name: impl $crate::glib::IntoGStr,
1584            iter: impl IntoIterator<Item = I>,
1585        ) -> Self {
1586            let iter = iter.into_iter().map(|item| item.to_send_value());
1587            self.field(name, V::from_iter(iter))
1588        }
1589
1590        // rustdoc-stripper-ignore-next
1591        /// Sets field `name` using the given `ValueType` `V` built from `iter`'s the `Item`s.
1592        ///
1593        /// Overrides any default or previously defined value for `name`.
1594        #[inline]
1595        pub fn field_with_static_from_iter<
1596            V: $crate::glib::value::ValueType + Into<$crate::glib::Value> + FromIterator<$crate::glib::SendValue> + Send,
1597            I: $crate::glib::value::ToSendValue,
1598        >(
1599            self,
1600            name: impl AsRef<$crate::glib::GStr> + 'static,
1601            iter: impl IntoIterator<Item = I>,
1602        ) -> Self {
1603            let iter = iter.into_iter().map(|item| item.to_send_value());
1604            self.field_with_static(name, V::from_iter(iter))
1605        }
1606
1607        // rustdoc-stripper-ignore-next
1608        /// Sets field `name` using the given `ValueType` `V` built from `iter`'s the `Item`s.
1609        ///
1610        /// Overrides any default or previously defined value for `name`.
1611        #[inline]
1612        pub fn field_with_id_from_iter<
1613            V: $crate::glib::value::ValueType + Into<$crate::glib::Value> + FromIterator<$crate::glib::SendValue> + Send,
1614            I: $crate::glib::value::ToSendValue,
1615        >(
1616            self,
1617            name: impl AsRef<$crate::IdStr>,
1618            iter: impl IntoIterator<Item = I>,
1619        ) -> Self {
1620            let iter = iter.into_iter().map(|item| item.to_send_value());
1621            self.field_with_id(name, V::from_iter(iter))
1622        }
1623
1624        // rustdoc-stripper-ignore-next
1625        /// Sets field `name` using the given `ValueType` `V` built from `iter`'s Item`s,
1626        /// if `iter` is not empty.
1627        ///
1628        /// This has no effect if `iter` is empty, i.e. previous value for `name` is unchanged.
1629        #[inline]
1630        pub fn field_if_not_empty<
1631            V: $crate::glib::value::ValueType + Into<$crate::glib::Value> + FromIterator<$crate::glib::SendValue> + Send,
1632            I: $crate::glib::value::ToSendValue,
1633        >(
1634            self,
1635            name: impl $crate::glib::IntoGStr,
1636            iter: impl IntoIterator<Item = I>,
1637        ) -> Self {
1638            let mut iter = iter.into_iter().peekable();
1639            if iter.peek().is_some() {
1640                let iter = iter.map(|item| item.to_send_value());
1641                self.field(name, V::from_iter(iter))
1642            } else {
1643                self
1644            }
1645        }
1646
1647        // rustdoc-stripper-ignore-next
1648        /// Sets field `name` using the given `ValueType` `V` built from `iter`'s Item`s,
1649        /// if `iter` is not empty.
1650        ///
1651        /// This has no effect if `iter` is empty, i.e. previous value for `name` is unchanged.
1652        #[inline]
1653        pub fn field_with_static_if_not_empty<
1654            V: $crate::glib::value::ValueType + Into<$crate::glib::Value> + FromIterator<$crate::glib::SendValue> + Send,
1655            I: $crate::glib::value::ToSendValue,
1656        >(
1657            self,
1658            name: impl AsRef<$crate::glib::GStr> + 'static,
1659            iter: impl IntoIterator<Item = I>,
1660        ) -> Self {
1661            let mut iter = iter.into_iter().peekable();
1662            if iter.peek().is_some() {
1663                let iter = iter.map(|item| item.to_send_value());
1664                self.field_with_static(name, V::from_iter(iter))
1665            } else {
1666                self
1667            }
1668        }
1669
1670        // rustdoc-stripper-ignore-next
1671        /// Sets field `name` using the given `ValueType` `V` built from `iter`'s Item`s,
1672        /// if `iter` is not empty.
1673        ///
1674        /// This has no effect if `iter` is empty, i.e. previous value for `name` is unchanged.
1675        #[inline]
1676        pub fn field_with_id_if_not_empty
1677            <V: $crate::glib::value::ValueType + Into<$crate::glib::Value> + FromIterator<$crate::glib::SendValue> + Send,
1678            I: $crate::glib::value::ToSendValue,
1679        >(
1680            self,
1681            name: impl AsRef<IdStr>,
1682            iter: impl IntoIterator<Item = I>,
1683        ) -> Self {
1684            let mut iter = iter.into_iter().peekable();
1685            if iter.peek().is_some() {
1686                let iter = iter.map(|item| item.to_send_value());
1687                self.field_with_id(name, V::from_iter(iter))
1688            } else {
1689                self
1690            }
1691        }
1692    };
1693
1694    (other_field) => {
1695        // rustdoc-stripper-ignore-next
1696        /// Sets field `name` to the given inner value if the `predicate` evaluates to `true`.
1697        ///
1698        /// This has no effect if the `predicate` evaluates to `false`,
1699        /// i.e. default or previous value for `name` is kept.
1700        #[inline]
1701        pub fn other_field_if(self, name: &'a str, value: impl $crate::glib::value::ToSendValue, predicate: bool) -> Self {
1702            if predicate {
1703                self.other_field(name, value)
1704            } else {
1705                self
1706            }
1707        }
1708
1709        // rustdoc-stripper-ignore-next
1710        /// Sets field `name` to the given inner value if `value` is `Some`.
1711        ///
1712        /// This has no effect if the value is `None`, i.e. default or previous value for `name` is kept.
1713        #[inline]
1714        pub fn other_field_if_some(self, name: &'a str, value: Option<impl $crate::glib::value::ToSendValue>) -> Self {
1715            if let Some(value) = value {
1716                self.other_field(name, value)
1717            } else {
1718                self
1719            }
1720        }
1721
1722        // rustdoc-stripper-ignore-next
1723        /// Sets field `name` using the given `ValueType` `V` built from `iter`'s the `Item`s.
1724        ///
1725        /// Overrides any default or previously defined value for `name`.
1726        #[inline]
1727        pub fn other_field_from_iter<
1728            V: $crate::glib::value::ValueType + $crate::glib::value::ToSendValue + FromIterator<$crate::glib::SendValue>,
1729            I: $crate::glib::value::ToSendValue,
1730        >(
1731            self,
1732            name: &'a str,
1733            iter: impl IntoIterator<Item = I>,
1734        ) -> Self {
1735            let iter = iter.into_iter().map(|item| item.to_send_value());
1736            self.other_field(name, V::from_iter(iter))
1737        }
1738
1739        // rustdoc-stripper-ignore-next
1740        /// Sets field `name` using the given `ValueType` `V` built from `iter`'s Item`s,
1741        /// if `iter` is not empty.
1742        ///
1743        /// This has no effect if `iter` is empty, i.e. previous value for `name` is unchanged.
1744        #[inline]
1745        pub fn other_field_if_not_empty<
1746            V: $crate::glib::value::ValueType + $crate::glib::value::ToSendValue + FromIterator<$crate::glib::SendValue>,
1747            I: $crate::glib::value::ToSendValue,
1748        >(
1749            self,
1750            name: &'a str,
1751            iter: impl IntoIterator<Item = I>,
1752        ) -> Self {
1753            let mut iter = iter.into_iter().peekable();
1754            if iter.peek().is_some() {
1755                let iter = iter.map(|item| item.to_send_value());
1756                self.other_field(name, V::from_iter(iter))
1757            } else {
1758                self
1759            }
1760        }
1761     };
1762
1763    (property_and_name) => {
1764        // rustdoc-stripper-ignore-next
1765        /// Sets property `name` to the given inner value if the `predicate` evaluates to `true`.
1766        ///
1767        /// This has no effect if the `predicate` evaluates to `false`,
1768        /// i.e. default or previous value for `name` is kept.
1769        #[inline]
1770        pub fn property_if(self, name: &'a str, value: impl Into<$crate::glib::Value> + 'a, predicate: bool) -> Self {
1771            if predicate {
1772                self.property(name, value)
1773            } else {
1774                self
1775            }
1776        }
1777
1778        // rustdoc-stripper-ignore-next
1779        /// Sets property `name` to the given inner value if `value` is `Some`.
1780        ///
1781        /// This has no effect if the value is `None`, i.e. default or previous value for `name` is kept.
1782        #[inline]
1783        pub fn property_if_some(self, name: &'a str, value: Option<impl Into<$crate::glib::Value> + 'a>) -> Self {
1784            if let Some(value) = value {
1785                self.property(name, value)
1786            } else {
1787                self
1788            }
1789        }
1790
1791        // rustdoc-stripper-ignore-next
1792        /// Sets property `name` using the given `ValueType` `V` built from `iter`'s the `Item`s.
1793        ///
1794        /// Overrides any default or previously defined value for `name`.
1795        #[inline]
1796        pub fn property_from_iter<
1797            V: $crate::glib::value::ValueType + Into<$crate::glib::Value> + FromIterator<$crate::glib::SendValue>,
1798            I: $crate::glib::value::ToSendValue,
1799        >(
1800            self,
1801            name: &'a str,
1802            iter: impl IntoIterator<Item = I>,
1803        ) -> Self {
1804            let iter = iter.into_iter().map(|item| item.to_send_value());
1805            self.property(name, V::from_iter(iter))
1806        }
1807
1808        // rustdoc-stripper-ignore-next
1809        /// Sets property `name` using the given `ValueType` `V` built from `iter`'s Item`s,
1810        /// if `iter` is not empty.
1811        ///
1812        /// This has no effect if `iter` is empty, i.e. previous value for `name` is unchanged.
1813        #[inline]
1814        pub fn property_if_not_empty<
1815            V: $crate::glib::value::ValueType + Into<$crate::glib::Value> + FromIterator<$crate::glib::SendValue>,
1816            I: $crate::glib::value::ToSendValue,
1817        >(
1818            self,
1819            name: &'a str,
1820            iter: impl IntoIterator<Item = I>,
1821        ) -> Self {
1822            let mut iter = iter.into_iter().peekable();
1823            if iter.peek().is_some() {
1824                let iter = iter.map(|item| item.to_send_value());
1825                self.property(name, V::from_iter(iter))
1826            } else {
1827                self
1828            }
1829        }
1830
1831        // rustdoc-stripper-ignore-next
1832        /// Sets property `name` to the given string value `value` if the `predicate` evaluates to `true`.
1833        ///
1834        /// This has no effect if the `predicate` evaluates to `false`,
1835        /// i.e. default or previous value for `name` is kept.
1836        #[inline]
1837        pub fn property_from_str_if(self, name: &'a str, value: &'a str, predicate: bool) -> Self {
1838            if predicate {
1839                self.property_from_str(name, value)
1840            } else {
1841                self
1842            }
1843        }
1844
1845        // rustdoc-stripper-ignore-next
1846        /// Sets property `name` to the given string value `value` if it is `Some`.
1847        ///
1848        /// This has no effect if the value is `None`, i.e. default or previous value for `name` is kept.
1849        #[inline]
1850        pub fn property_from_str_if_some(self, name: &'a str, value: Option<&'a str>) -> Self {
1851            if let Some(value) = value {
1852                self.property_from_str(name, value)
1853            } else {
1854                self
1855            }
1856        }
1857
1858        // rustdoc-stripper-ignore-next
1859        /// Sets the name property to the given `name`.
1860        #[inline]
1861        pub fn name(self, name: impl Into<$crate::glib::GString>) -> Self {
1862            self.property("name", name.into())
1863        }
1864
1865        // rustdoc-stripper-ignore-next
1866        /// Sets the name property to the given `name` if the `predicate` evaluates to `true`.
1867        ///
1868        /// This has no effect if the `predicate` evaluates to `false`,
1869        /// i.e. default or previous name is kept.
1870        #[inline]
1871        pub fn name_if(self, name: impl Into<$crate::glib::GString>, predicate: bool) -> Self {
1872            if predicate {
1873                self.name(name)
1874            } else {
1875                self
1876            }
1877        }
1878
1879        // rustdoc-stripper-ignore-next
1880        /// Sets the name property to the given `name` if it is `Some`.
1881        ///
1882        /// This has no effect if the value is `None`, i.e. default or previous name is kept.
1883        #[inline]
1884        pub fn name_if_some(self, name: Option<impl Into<$crate::glib::GString>>) -> Self {
1885            if let Some(name) = name {
1886                self.name(name)
1887            } else {
1888                self
1889            }
1890        }
1891     };
1892);
1893
1894#[cfg(test)]
1895mod tests {
1896    use super::*;
1897
1898    #[test]
1899    fn test_fraction() {
1900        crate::init().unwrap();
1901
1902        let f1 = crate::Fraction::new(1, 2);
1903        let f2 = crate::Fraction::new(2, 3);
1904        let mut f3 = f1 * f2;
1905        let f4 = f1 * f2;
1906        f3 *= f2;
1907        f3 *= f4;
1908
1909        assert_eq!(f3, crate::Fraction::new(2, 27));
1910    }
1911
1912    #[test]
1913    fn test_int_range_constructor() {
1914        crate::init().unwrap();
1915
1916        // Type inference should figure out the type
1917        let _r1 = crate::IntRange::new(1i32, 2i32);
1918        let _r2 = crate::IntRange::with_step(2i64, 10i64, 2i64);
1919        let _r3 = crate::IntRange::with_step(0i64, 6i64, 3i64);
1920    }
1921
1922    #[test]
1923    #[should_panic(expected = "step size must be greater than zero")]
1924    fn test_int_range_constructor_step0() {
1925        crate::init().unwrap();
1926        let _r = crate::IntRange::with_step(0i32, 2i32, 0i32);
1927    }
1928
1929    #[test]
1930    #[should_panic(expected = "maximum value must be greater than minimum value")]
1931    fn test_int_range_constructor_max_min() {
1932        crate::init().unwrap();
1933        let _r = crate::IntRange::with_step(4i32, 2i32, 2i32);
1934    }
1935
1936    #[test]
1937    #[should_panic(expected = "maximum value must be greater than minimum value")]
1938    fn test_int_range_constructor_max_eq_min() {
1939        crate::init().unwrap();
1940        let _r = crate::IntRange::with_step(4i32, 4i32, 2i32);
1941    }
1942
1943    #[test]
1944    #[should_panic(expected = "minimum value must be evenly dividable by step size")]
1945    fn test_int_range_constructor_bad_step() {
1946        crate::init().unwrap();
1947        let _r = crate::IntRange::with_step(1i32, 10i32, 2i32);
1948    }
1949
1950    #[test]
1951    #[should_panic(expected = "maximum value must be evenly dividable by step size")]
1952    fn test_int_range_constructor_bad_step_max() {
1953        crate::init().unwrap();
1954        let _r = crate::IntRange::with_step(0i32, 10i32, 3i32);
1955    }
1956
1957    #[test]
1958    #[should_panic(expected = "step size must be greater than zero")]
1959    fn test_int_range_constructor_step0_i64() {
1960        crate::init().unwrap();
1961        let _r = crate::IntRange::with_step(0i64, 2i64, 0i64);
1962    }
1963
1964    #[test]
1965    #[should_panic(expected = "maximum value must be greater than minimum value")]
1966    fn test_int_range_constructor_max_min_i64() {
1967        crate::init().unwrap();
1968        let _r = crate::IntRange::with_step(4i64, 2i64, 2i64);
1969    }
1970
1971    #[test]
1972    #[should_panic(expected = "maximum value must be greater than minimum value")]
1973    fn test_int_range_constructor_max_eq_min_i64() {
1974        crate::init().unwrap();
1975        let _r = crate::IntRange::with_step(4i64, 4i64, 2i64);
1976    }
1977
1978    #[test]
1979    #[should_panic(expected = "minimum value must be evenly dividable by step size")]
1980    fn test_int_range_constructor_bad_step_i64() {
1981        crate::init().unwrap();
1982        let _r = crate::IntRange::with_step(1i64, 10i64, 2i64);
1983    }
1984    #[test]
1985    #[should_panic(expected = "maximum value must be evenly dividable by step size")]
1986    fn test_int_range_constructor_bad_step_max_i64() {
1987        crate::init().unwrap();
1988        let _r = crate::IntRange::with_step(0i64, 10i64, 3i64);
1989    }
1990
1991    #[test]
1992    fn test_deserialize() {
1993        crate::init().unwrap();
1994
1995        let v = glib::Value::deserialize("123", i32::static_type()).unwrap();
1996        assert_eq!(v.get::<i32>(), Ok(123));
1997    }
1998}