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