1use 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 #[inline]
20 pub fn new(numer: i32, denom: i32) -> Self {
21 skip_assert_initialized!();
22 (numer, denom).into()
23 }
24
25 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 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}