1 // Copyright (C) 2017 Sebastian Dröge <sebastian@centricular.com>
2 //
3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6 // option. This file may not be copied, modified, or distributed
7 // except according to those terms.
8 
9 use num_rational::Rational32;
10 use std::borrow::{Borrow, Cow};
11 use std::cmp;
12 use std::fmt;
13 use std::ops;
14 use std::slice;
15 
16 use glib;
17 use glib::translate::{from_glib, FromGlibPtrFull, ToGlibPtr, ToGlibPtrMut, Uninitialized};
18 use glib::value::{FromValue, FromValueOptional, SetValue, ToSendValue, Value};
19 
20 use glib_sys;
21 use gst_sys;
22 
23 #[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
24 pub struct Fraction(pub Rational32);
25 
26 impl Fraction {
new(num: i32, den: i32) -> Fraction27     pub fn new(num: i32, den: i32) -> Fraction {
28         assert_initialized_main_thread!();
29         (num, den).into()
30     }
31 
approximate_f32(x: f32) -> Option<Fraction>32     pub fn approximate_f32(x: f32) -> Option<Fraction> {
33         assert_initialized_main_thread!();
34         Rational32::approximate_float(x).map(|r| r.into())
35     }
36 
approximate_f64(x: f64) -> Option<Fraction>37     pub fn approximate_f64(x: f64) -> Option<Fraction> {
38         assert_initialized_main_thread!();
39         Rational32::approximate_float(x).map(|r| r.into())
40     }
41 }
42 
43 impl fmt::Display for Fraction {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result44     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
45         self.0.fmt(f)
46     }
47 }
48 
49 impl ops::Deref for Fraction {
50     type Target = Rational32;
51 
deref(&self) -> &Rational3252     fn deref(&self) -> &Rational32 {
53         &self.0
54     }
55 }
56 
57 impl ops::DerefMut for Fraction {
deref_mut(&mut self) -> &mut Rational3258     fn deref_mut(&mut self) -> &mut Rational32 {
59         &mut self.0
60     }
61 }
62 
63 impl AsRef<Rational32> for Fraction {
as_ref(&self) -> &Rational3264     fn as_ref(&self) -> &Rational32 {
65         &self.0
66     }
67 }
68 
69 macro_rules! impl_fraction_binop {
70     ($name:ident, $f:ident, $name_assign:ident, $f_assign:ident) => {
71         impl ops::$name<Fraction> for Fraction {
72             type Output = Fraction;
73 
74             fn $f(self, other: Fraction) -> Fraction {
75                 Fraction((self.0).$f(other.0))
76             }
77         }
78 
79         impl ops::$name<Fraction> for &Fraction {
80             type Output = Fraction;
81 
82             fn $f(self, other: Fraction) -> Fraction {
83                 Fraction((self.0).$f(other.0))
84             }
85         }
86 
87         impl ops::$name<&Fraction> for Fraction {
88             type Output = Fraction;
89 
90             fn $f(self, other: &Fraction) -> Fraction {
91                 Fraction((self.0).$f(other.0))
92             }
93         }
94 
95         impl ops::$name<&Fraction> for &Fraction {
96             type Output = Fraction;
97 
98             fn $f(self, other: &Fraction) -> Fraction {
99                 Fraction((self.0).$f(other.0))
100             }
101         }
102 
103         impl ops::$name<i32> for Fraction {
104             type Output = Fraction;
105 
106             fn $f(self, other: i32) -> Fraction {
107                 self.$f(Fraction::from(other))
108             }
109         }
110 
111         impl ops::$name<i32> for &Fraction {
112             type Output = Fraction;
113 
114             fn $f(self, other: i32) -> Fraction {
115                 self.$f(Fraction::from(other))
116             }
117         }
118 
119         impl ops::$name<&i32> for Fraction {
120             type Output = Fraction;
121 
122             fn $f(self, other: &i32) -> Fraction {
123                 self.$f(Fraction::from(*other))
124             }
125         }
126 
127         impl ops::$name<&i32> for &Fraction {
128             type Output = Fraction;
129 
130             fn $f(self, other: &i32) -> Fraction {
131                 self.$f(Fraction::from(*other))
132             }
133         }
134 
135         impl ops::$name<Fraction> for i32 {
136             type Output = Fraction;
137 
138             fn $f(self, other: Fraction) -> Fraction {
139                 Fraction::from(self).$f(other)
140             }
141         }
142 
143         impl ops::$name<&Fraction> for i32 {
144             type Output = Fraction;
145 
146             fn $f(self, other: &Fraction) -> Fraction {
147                 Fraction::from(self).$f(other)
148             }
149         }
150 
151         impl ops::$name<Fraction> for &i32 {
152             type Output = Fraction;
153 
154             fn $f(self, other: Fraction) -> Fraction {
155                 Fraction::from(*self).$f(other)
156             }
157         }
158 
159         impl ops::$name<&Fraction> for &i32 {
160             type Output = Fraction;
161 
162             fn $f(self, other: &Fraction) -> Fraction {
163                 Fraction::from(*self).$f(other)
164             }
165         }
166 
167         impl ops::$name_assign<Fraction> for Fraction {
168             fn $f_assign(&mut self, other: Fraction) {
169                 (self.0).$f_assign(other.0)
170             }
171         }
172 
173         impl ops::$name_assign<&Fraction> for Fraction {
174             fn $f_assign(&mut self, other: &Fraction) {
175                 (self.0).$f_assign(other.0)
176             }
177         }
178 
179         impl ops::$name_assign<i32> for Fraction {
180             fn $f_assign(&mut self, other: i32) {
181                 (self.0).$f_assign(other)
182             }
183         }
184 
185         impl ops::$name_assign<&i32> for Fraction {
186             fn $f_assign(&mut self, other: &i32) {
187                 (self.0).$f_assign(other)
188             }
189         }
190     };
191 }
192 
193 impl_fraction_binop!(Add, add, AddAssign, add_assign);
194 impl_fraction_binop!(Sub, sub, SubAssign, sub_assign);
195 impl_fraction_binop!(Div, div, DivAssign, div_assign);
196 impl_fraction_binop!(Mul, mul, MulAssign, mul_assign);
197 impl_fraction_binop!(Rem, rem, RemAssign, rem_assign);
198 
199 impl ops::Neg for Fraction {
200     type Output = Fraction;
201 
neg(self) -> Fraction202     fn neg(self) -> Fraction {
203         Fraction(self.0.neg())
204     }
205 }
206 
207 impl ops::Neg for &Fraction {
208     type Output = Fraction;
209 
neg(self) -> Fraction210     fn neg(self) -> Fraction {
211         Fraction(self.0.neg())
212     }
213 }
214 
215 impl From<i32> for Fraction {
from(x: i32) -> Fraction216     fn from(x: i32) -> Fraction {
217         assert_initialized_main_thread!();
218         Fraction(x.into())
219     }
220 }
221 
222 impl From<(i32, i32)> for Fraction {
from(x: (i32, i32)) -> Fraction223     fn from(x: (i32, i32)) -> Fraction {
224         assert_initialized_main_thread!();
225         Fraction(x.into())
226     }
227 }
228 
229 impl Into<(i32, i32)> for Fraction {
into(self) -> (i32, i32)230     fn into(self) -> (i32, i32) {
231         self.0.into()
232     }
233 }
234 
235 impl From<Rational32> for Fraction {
from(x: Rational32) -> Fraction236     fn from(x: Rational32) -> Fraction {
237         assert_initialized_main_thread!();
238         Fraction(x)
239     }
240 }
241 
242 impl From<Fraction> for Rational32 {
from(x: Fraction) -> Rational32243     fn from(x: Fraction) -> Rational32 {
244         skip_assert_initialized!();
245         x.0
246     }
247 }
248 
249 impl glib::types::StaticType for Fraction {
static_type() -> glib::types::Type250     fn static_type() -> glib::types::Type {
251         unsafe { from_glib(gst_sys::gst_fraction_get_type()) }
252     }
253 }
254 
255 impl<'a> FromValue<'a> for Fraction {
from_value(v: &'a Value) -> Fraction256     unsafe fn from_value(v: &'a Value) -> Fraction {
257         let n = gst_sys::gst_value_get_fraction_numerator(v.to_glib_none().0);
258         let d = gst_sys::gst_value_get_fraction_denominator(v.to_glib_none().0);
259 
260         Fraction::new(n, d)
261     }
262 }
263 
264 impl<'a> FromValueOptional<'a> for Fraction {
from_value_optional(v: &'a Value) -> Option<Fraction>265     unsafe fn from_value_optional(v: &'a Value) -> Option<Fraction> {
266         Some(Fraction::from_value(v))
267     }
268 }
269 
270 impl SetValue for Fraction {
set_value(v: &mut Value, f: &Self)271     unsafe fn set_value(v: &mut Value, f: &Self) {
272         gst_sys::gst_value_set_fraction(v.to_glib_none_mut().0, *f.numer(), *f.denom());
273     }
274 }
275 
276 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
277 #[cfg_attr(feature = "ser_de", derive(Serialize, Deserialize))]
278 pub struct IntRange<T> {
279     min: T,
280     max: T,
281     step: T,
282 }
283 
284 impl<T: Copy> IntRange<T> {
min(&self) -> T285     pub fn min(&self) -> T {
286         self.min
287     }
288 
max(&self) -> T289     pub fn max(&self) -> T {
290         self.max
291     }
292 
step(&self) -> T293     pub fn step(&self) -> T {
294         self.step
295     }
296 }
297 
298 impl IntRange<i32> {
new(min: i32, max: i32) -> Self299     pub fn new(min: i32, max: i32) -> Self {
300         skip_assert_initialized!();
301         Self::new_with_step(min, max, 1)
302     }
303 
new_with_step(min: i32, max: i32, step: i32) -> Self304     pub fn new_with_step(min: i32, max: i32, step: i32) -> Self {
305         assert_initialized_main_thread!();
306 
307         assert!(min <= max);
308         assert!(step > 0);
309 
310         Self { min, max, step }
311     }
312 }
313 
314 impl IntRange<i64> {
new(min: i64, max: i64) -> Self315     pub fn new(min: i64, max: i64) -> Self {
316         skip_assert_initialized!();
317         Self::new_with_step(min, max, 1)
318     }
319 
new_with_step(min: i64, max: i64, step: i64) -> Self320     pub fn new_with_step(min: i64, max: i64, step: i64) -> Self {
321         assert_initialized_main_thread!();
322 
323         assert!(min <= max);
324         assert!(step > 0);
325 
326         Self { min, max, step }
327     }
328 }
329 
330 impl From<(i32, i32)> for IntRange<i32> {
from((min, max): (i32, i32)) -> Self331     fn from((min, max): (i32, i32)) -> Self {
332         skip_assert_initialized!();
333         Self::new(min, max)
334     }
335 }
336 
337 impl From<(i32, i32, i32)> for IntRange<i32> {
from((min, max, step): (i32, i32, i32)) -> Self338     fn from((min, max, step): (i32, i32, i32)) -> Self {
339         skip_assert_initialized!();
340         Self::new_with_step(min, max, step)
341     }
342 }
343 
344 impl From<(i64, i64)> for IntRange<i64> {
from((min, max): (i64, i64)) -> Self345     fn from((min, max): (i64, i64)) -> Self {
346         skip_assert_initialized!();
347         Self::new(min, max)
348     }
349 }
350 
351 impl From<(i64, i64, i64)> for IntRange<i64> {
from((min, max, step): (i64, i64, i64)) -> Self352     fn from((min, max, step): (i64, i64, i64)) -> Self {
353         skip_assert_initialized!();
354         Self::new_with_step(min, max, step)
355     }
356 }
357 
358 impl glib::types::StaticType for IntRange<i32> {
static_type() -> glib::types::Type359     fn static_type() -> glib::types::Type {
360         unsafe { from_glib(gst_sys::gst_int_range_get_type()) }
361     }
362 }
363 
364 impl<'a> FromValue<'a> for IntRange<i32> {
from_value(v: &'a Value) -> Self365     unsafe fn from_value(v: &'a Value) -> Self {
366         let min = gst_sys::gst_value_get_int_range_min(v.to_glib_none().0);
367         let max = gst_sys::gst_value_get_int_range_max(v.to_glib_none().0);
368         let step = gst_sys::gst_value_get_int_range_step(v.to_glib_none().0);
369 
370         Self::new_with_step(min, max, step)
371     }
372 }
373 
374 impl<'a> FromValueOptional<'a> for IntRange<i32> {
from_value_optional(v: &'a Value) -> Option<Self>375     unsafe fn from_value_optional(v: &'a Value) -> Option<Self> {
376         Some(Self::from_value(v))
377     }
378 }
379 
380 impl SetValue for IntRange<i32> {
set_value(v: &mut Value, r: &Self)381     unsafe fn set_value(v: &mut Value, r: &Self) {
382         gst_sys::gst_value_set_int_range_step(v.to_glib_none_mut().0, r.min(), r.max(), r.step());
383     }
384 }
385 
386 impl glib::types::StaticType for IntRange<i64> {
static_type() -> glib::types::Type387     fn static_type() -> glib::types::Type {
388         unsafe { from_glib(gst_sys::gst_int64_range_get_type()) }
389     }
390 }
391 
392 impl<'a> FromValue<'a> for IntRange<i64> {
from_value(v: &'a Value) -> Self393     unsafe fn from_value(v: &'a Value) -> Self {
394         let min = gst_sys::gst_value_get_int64_range_min(v.to_glib_none().0);
395         let max = gst_sys::gst_value_get_int64_range_max(v.to_glib_none().0);
396         let step = gst_sys::gst_value_get_int64_range_step(v.to_glib_none().0);
397 
398         Self::new_with_step(min, max, step)
399     }
400 }
401 
402 impl<'a> FromValueOptional<'a> for IntRange<i64> {
from_value_optional(v: &'a Value) -> Option<Self>403     unsafe fn from_value_optional(v: &'a Value) -> Option<Self> {
404         Some(Self::from_value(v))
405     }
406 }
407 
408 impl SetValue for IntRange<i64> {
set_value(v: &mut Value, r: &Self)409     unsafe fn set_value(v: &mut Value, r: &Self) {
410         gst_sys::gst_value_set_int64_range_step(v.to_glib_none_mut().0, r.min(), r.max(), r.step());
411     }
412 }
413 
414 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
415 #[cfg_attr(feature = "ser_de", derive(Serialize, Deserialize))]
416 pub struct FractionRange {
417     min: Fraction,
418     max: Fraction,
419 }
420 
421 impl FractionRange {
new<T: Into<Fraction>, U: Into<Fraction>>(min: T, max: U) -> Self422     pub fn new<T: Into<Fraction>, U: Into<Fraction>>(min: T, max: U) -> Self {
423         assert_initialized_main_thread!();
424 
425         let min = min.into();
426         let max = max.into();
427 
428         assert!(min <= max);
429 
430         FractionRange { min, max }
431     }
432 
min(&self) -> Fraction433     pub fn min(&self) -> Fraction {
434         self.min
435     }
436 
max(&self) -> Fraction437     pub fn max(&self) -> Fraction {
438         self.max
439     }
440 }
441 
442 impl From<(Fraction, Fraction)> for FractionRange {
from((min, max): (Fraction, Fraction)) -> Self443     fn from((min, max): (Fraction, Fraction)) -> Self {
444         skip_assert_initialized!();
445 
446         Self::new(min, max)
447     }
448 }
449 
450 impl glib::types::StaticType for FractionRange {
static_type() -> glib::types::Type451     fn static_type() -> glib::types::Type {
452         unsafe { from_glib(gst_sys::gst_fraction_range_get_type()) }
453     }
454 }
455 
456 impl<'a> FromValue<'a> for FractionRange {
from_value(v: &'a Value) -> Self457     unsafe fn from_value(v: &'a Value) -> Self {
458         let min = gst_sys::gst_value_get_fraction_range_min(v.to_glib_none().0);
459         let max = gst_sys::gst_value_get_fraction_range_max(v.to_glib_none().0);
460 
461         let min_n = gst_sys::gst_value_get_fraction_numerator(min);
462         let min_d = gst_sys::gst_value_get_fraction_denominator(min);
463         let max_n = gst_sys::gst_value_get_fraction_numerator(max);
464         let max_d = gst_sys::gst_value_get_fraction_denominator(max);
465 
466         Self::new((min_n, min_d), (max_n, max_d))
467     }
468 }
469 
470 impl<'a> FromValueOptional<'a> for FractionRange {
from_value_optional(v: &'a Value) -> Option<Self>471     unsafe fn from_value_optional(v: &'a Value) -> Option<Self> {
472         Some(Self::from_value(v))
473     }
474 }
475 
476 impl SetValue for FractionRange {
set_value(v: &mut Value, r: &Self)477     unsafe fn set_value(v: &mut Value, r: &Self) {
478         gst_sys::gst_value_set_fraction_range_full(
479             v.to_glib_none_mut().0,
480             *r.min().numer(),
481             *r.min().denom(),
482             *r.max().numer(),
483             *r.max().denom(),
484         );
485     }
486 }
487 
488 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
489 #[cfg_attr(feature = "ser_de", derive(Serialize, Deserialize))]
490 pub struct Bitmask(pub u64);
491 
492 impl Bitmask {
new(v: u64) -> Self493     pub fn new(v: u64) -> Self {
494         assert_initialized_main_thread!();
495         Bitmask(v)
496     }
497 }
498 
499 impl ops::Deref for Bitmask {
500     type Target = u64;
501 
deref(&self) -> &u64502     fn deref(&self) -> &u64 {
503         &self.0
504     }
505 }
506 
507 impl ops::DerefMut for Bitmask {
deref_mut(&mut self) -> &mut u64508     fn deref_mut(&mut self) -> &mut u64 {
509         &mut self.0
510     }
511 }
512 
513 impl ops::BitAnd for Bitmask {
514     type Output = Self;
515 
bitand(self, rhs: Self) -> Self516     fn bitand(self, rhs: Self) -> Self {
517         Bitmask(self.0.bitand(rhs.0))
518     }
519 }
520 
521 impl ops::BitOr for Bitmask {
522     type Output = Self;
523 
bitor(self, rhs: Self) -> Self524     fn bitor(self, rhs: Self) -> Self {
525         Bitmask(self.0.bitor(rhs.0))
526     }
527 }
528 
529 impl ops::BitXor for Bitmask {
530     type Output = Self;
531 
bitxor(self, rhs: Self) -> Self532     fn bitxor(self, rhs: Self) -> Self {
533         Bitmask(self.0.bitxor(rhs.0))
534     }
535 }
536 
537 impl ops::Not for Bitmask {
538     type Output = Self;
539 
not(self) -> Self540     fn not(self) -> Self {
541         Bitmask(self.0.not())
542     }
543 }
544 
545 impl From<u64> for Bitmask {
from(v: u64) -> Self546     fn from(v: u64) -> Self {
547         skip_assert_initialized!();
548         Self::new(v)
549     }
550 }
551 
552 impl glib::types::StaticType for Bitmask {
static_type() -> glib::types::Type553     fn static_type() -> glib::types::Type {
554         unsafe { from_glib(gst_sys::gst_bitmask_get_type()) }
555     }
556 }
557 
558 impl<'a> FromValue<'a> for Bitmask {
from_value(v: &'a Value) -> Self559     unsafe fn from_value(v: &'a Value) -> Self {
560         let v = gst_sys::gst_value_get_bitmask(v.to_glib_none().0);
561         Self::new(v)
562     }
563 }
564 
565 impl<'a> FromValueOptional<'a> for Bitmask {
from_value_optional(v: &'a Value) -> Option<Self>566     unsafe fn from_value_optional(v: &'a Value) -> Option<Self> {
567         Some(Self::from_value(v))
568     }
569 }
570 
571 impl SetValue for Bitmask {
set_value(v: &mut Value, r: &Self)572     unsafe fn set_value(v: &mut Value, r: &Self) {
573         gst_sys::gst_value_set_bitmask(v.to_glib_none_mut().0, r.0);
574     }
575 }
576 
577 #[derive(Clone, Debug)]
578 pub struct Array<'a>(Cow<'a, [glib::SendValue]>);
579 
580 unsafe impl<'a> Send for Array<'a> {}
581 
582 impl<'a> Array<'a> {
new(values: &[&dyn ToSendValue]) -> Self583     pub fn new(values: &[&dyn ToSendValue]) -> Self {
584         assert_initialized_main_thread!();
585 
586         Array(values.iter().map(|v| v.to_send_value()).collect())
587     }
588 
from_owned(values: Vec<glib::SendValue>) -> Self589     pub fn from_owned(values: Vec<glib::SendValue>) -> Self {
590         assert_initialized_main_thread!();
591 
592         Array(Cow::Owned(values))
593     }
594 
into_owned(self) -> Array<'static>595     pub fn into_owned(self) -> Array<'static> {
596         Array(self.0.into_owned().into())
597     }
598 
as_slice(&self) -> &[glib::SendValue]599     pub fn as_slice(&self) -> &[glib::SendValue] {
600         self.0.borrow()
601     }
602 }
603 
604 impl<'a> From<&'a [&'a dyn ToSendValue]> for Array<'a> {
from(values: &'a [&'a dyn ToSendValue]) -> Self605     fn from(values: &'a [&'a dyn ToSendValue]) -> Self {
606         skip_assert_initialized!();
607 
608         Self::new(values)
609     }
610 }
611 
612 impl<'a> From<&'a [glib::SendValue]> for Array<'a> {
from(values: &'a [glib::SendValue]) -> Self613     fn from(values: &'a [glib::SendValue]) -> Self {
614         assert_initialized_main_thread!();
615 
616         Array(Cow::Borrowed(values))
617     }
618 }
619 
620 impl<'a> FromValue<'a> for Array<'a> {
from_value(v: &'a Value) -> Self621     unsafe fn from_value(v: &'a Value) -> Self {
622         let arr = (*v.to_glib_none().0).data[0].v_pointer as *const glib_sys::GArray;
623         if arr.is_null() {
624             Array(Cow::Borrowed(&[]))
625         } else {
626             #[allow(clippy::cast_ptr_alignment)]
627             Array(Cow::Borrowed(slice::from_raw_parts(
628                 (*arr).data as *const glib::SendValue,
629                 (*arr).len as usize,
630             )))
631         }
632     }
633 }
634 
635 impl<'a> FromValueOptional<'a> for Array<'a> {
from_value_optional(v: &'a Value) -> Option<Self>636     unsafe fn from_value_optional(v: &'a Value) -> Option<Self> {
637         Some(Array::from_value(v))
638     }
639 }
640 
641 impl<'a> SetValue for Array<'a> {
set_value(v: &mut Value, a: &Self)642     unsafe fn set_value(v: &mut Value, a: &Self) {
643         for value in a.as_slice() {
644             gst_sys::gst_value_array_append_value(v.to_glib_none_mut().0, value.to_glib_none().0);
645         }
646     }
647 }
648 
649 impl<'a> glib::types::StaticType for Array<'a> {
static_type() -> glib::types::Type650     fn static_type() -> glib::types::Type {
651         unsafe { from_glib(gst_sys::gst_value_array_get_type()) }
652     }
653 }
654 
655 #[derive(Clone, Debug)]
656 pub struct List<'a>(Cow<'a, [glib::SendValue]>);
657 
658 unsafe impl<'a> Send for List<'a> {}
659 
660 impl<'a> List<'a> {
new(values: &[&dyn ToSendValue]) -> Self661     pub fn new(values: &[&dyn ToSendValue]) -> Self {
662         assert_initialized_main_thread!();
663 
664         List(values.iter().map(|v| v.to_send_value()).collect())
665     }
666 
from_owned(values: Vec<glib::SendValue>) -> Self667     pub fn from_owned(values: Vec<glib::SendValue>) -> Self {
668         assert_initialized_main_thread!();
669 
670         List(Cow::Owned(values))
671     }
672 
into_owned(self) -> List<'static>673     pub fn into_owned(self) -> List<'static> {
674         List(self.0.into_owned().into())
675     }
676 
as_slice(&self) -> &[glib::SendValue]677     pub fn as_slice(&self) -> &[glib::SendValue] {
678         self.0.borrow()
679     }
680 }
681 
682 impl<'a> From<&'a [&'a dyn ToSendValue]> for List<'a> {
from(values: &'a [&'a dyn ToSendValue]) -> Self683     fn from(values: &'a [&'a dyn ToSendValue]) -> Self {
684         skip_assert_initialized!();
685 
686         Self::new(values)
687     }
688 }
689 
690 impl<'a> From<&'a [glib::SendValue]> for List<'a> {
from(values: &'a [glib::SendValue]) -> Self691     fn from(values: &'a [glib::SendValue]) -> Self {
692         assert_initialized_main_thread!();
693 
694         List(Cow::Borrowed(values))
695     }
696 }
697 
698 impl<'a> FromValue<'a> for List<'a> {
from_value(v: &'a Value) -> Self699     unsafe fn from_value(v: &'a Value) -> Self {
700         let arr = (*v.to_glib_none().0).data[0].v_pointer as *const glib_sys::GArray;
701         if arr.is_null() {
702             List(Cow::Borrowed(&[]))
703         } else {
704             #[allow(clippy::cast_ptr_alignment)]
705             List(Cow::Borrowed(slice::from_raw_parts(
706                 (*arr).data as *const glib::SendValue,
707                 (*arr).len as usize,
708             )))
709         }
710     }
711 }
712 
713 impl<'a> FromValueOptional<'a> for List<'a> {
from_value_optional(v: &'a Value) -> Option<Self>714     unsafe fn from_value_optional(v: &'a Value) -> Option<Self> {
715         Some(List::from_value(v))
716     }
717 }
718 
719 impl<'a> SetValue for List<'a> {
set_value(v: &mut Value, a: &Self)720     unsafe fn set_value(v: &mut Value, a: &Self) {
721         for value in a.as_slice() {
722             gst_sys::gst_value_list_append_value(v.to_glib_none_mut().0, value.to_glib_none().0);
723         }
724     }
725 }
726 
727 impl<'a> glib::types::StaticType for List<'a> {
static_type() -> glib::types::Type728     fn static_type() -> glib::types::Type {
729         unsafe { from_glib(gst_sys::gst_value_list_get_type()) }
730     }
731 }
732 
733 pub trait GstValueExt: Sized {
can_compare(&self, other: &Self) -> bool734     fn can_compare(&self, other: &Self) -> bool;
compare(&self, other: &Self) -> Option<cmp::Ordering>735     fn compare(&self, other: &Self) -> Option<cmp::Ordering>;
eq(&self, other: &Self) -> bool736     fn eq(&self, other: &Self) -> bool;
can_intersect(&self, other: &Self) -> bool737     fn can_intersect(&self, other: &Self) -> bool;
intersect(&self, other: &Self) -> Option<Self>738     fn intersect(&self, other: &Self) -> Option<Self>;
can_subtract(&self, other: &Self) -> bool739     fn can_subtract(&self, other: &Self) -> bool;
subtract(&self, other: &Self) -> Option<Self>740     fn subtract(&self, other: &Self) -> Option<Self>;
can_union(&self, other: &Self) -> bool741     fn can_union(&self, other: &Self) -> bool;
union(&self, other: &Self) -> Option<Self>742     fn union(&self, other: &Self) -> Option<Self>;
fixate(&self) -> Option<Self>743     fn fixate(&self) -> Option<Self>;
is_fixed(&self) -> bool744     fn is_fixed(&self) -> bool;
is_subset(&self, superset: &Self) -> bool745     fn is_subset(&self, superset: &Self) -> bool;
serialize(&self) -> Result<glib::GString, glib::BoolError>746     fn serialize(&self) -> Result<glib::GString, glib::BoolError>;
deserialize<'a, T: Into<&'a str>>(s: T) -> Result<glib::Value, glib::BoolError>747     fn deserialize<'a, T: Into<&'a str>>(s: T) -> Result<glib::Value, glib::BoolError>;
748 }
749 
750 impl GstValueExt for glib::Value {
can_compare(&self, other: &Self) -> bool751     fn can_compare(&self, other: &Self) -> bool {
752         unsafe {
753             from_glib(gst_sys::gst_value_can_compare(
754                 self.to_glib_none().0,
755                 other.to_glib_none().0,
756             ))
757         }
758     }
759 
compare(&self, other: &Self) -> Option<cmp::Ordering>760     fn compare(&self, other: &Self) -> Option<cmp::Ordering> {
761         unsafe {
762             let val = gst_sys::gst_value_compare(self.to_glib_none().0, other.to_glib_none().0);
763 
764             match val {
765                 gst_sys::GST_VALUE_LESS_THAN => Some(cmp::Ordering::Less),
766                 gst_sys::GST_VALUE_EQUAL => Some(cmp::Ordering::Equal),
767                 gst_sys::GST_VALUE_GREATER_THAN => Some(cmp::Ordering::Greater),
768                 _ => None,
769             }
770         }
771     }
772 
eq(&self, other: &Self) -> bool773     fn eq(&self, other: &Self) -> bool {
774         self.compare(other) == Some(cmp::Ordering::Equal)
775     }
776 
can_intersect(&self, other: &Self) -> bool777     fn can_intersect(&self, other: &Self) -> bool {
778         unsafe {
779             from_glib(gst_sys::gst_value_can_intersect(
780                 self.to_glib_none().0,
781                 other.to_glib_none().0,
782             ))
783         }
784     }
785 
intersect(&self, other: &Self) -> Option<Self>786     fn intersect(&self, other: &Self) -> Option<Self> {
787         unsafe {
788             let mut value = glib::Value::uninitialized();
789             let ret: bool = from_glib(gst_sys::gst_value_intersect(
790                 value.to_glib_none_mut().0,
791                 self.to_glib_none().0,
792                 other.to_glib_none().0,
793             ));
794             if ret {
795                 Some(value)
796             } else {
797                 None
798             }
799         }
800     }
801 
can_subtract(&self, other: &Self) -> bool802     fn can_subtract(&self, other: &Self) -> bool {
803         unsafe {
804             from_glib(gst_sys::gst_value_can_subtract(
805                 self.to_glib_none().0,
806                 other.to_glib_none().0,
807             ))
808         }
809     }
810 
subtract(&self, other: &Self) -> Option<Self>811     fn subtract(&self, other: &Self) -> Option<Self> {
812         unsafe {
813             let mut value = glib::Value::uninitialized();
814             let ret: bool = from_glib(gst_sys::gst_value_subtract(
815                 value.to_glib_none_mut().0,
816                 self.to_glib_none().0,
817                 other.to_glib_none().0,
818             ));
819             if ret {
820                 Some(value)
821             } else {
822                 None
823             }
824         }
825     }
826 
can_union(&self, other: &Self) -> bool827     fn can_union(&self, other: &Self) -> bool {
828         unsafe {
829             from_glib(gst_sys::gst_value_can_union(
830                 self.to_glib_none().0,
831                 other.to_glib_none().0,
832             ))
833         }
834     }
835 
union(&self, other: &Self) -> Option<Self>836     fn union(&self, other: &Self) -> Option<Self> {
837         unsafe {
838             let mut value = glib::Value::uninitialized();
839             let ret: bool = from_glib(gst_sys::gst_value_union(
840                 value.to_glib_none_mut().0,
841                 self.to_glib_none().0,
842                 other.to_glib_none().0,
843             ));
844             if ret {
845                 Some(value)
846             } else {
847                 None
848             }
849         }
850     }
851 
fixate(&self) -> Option<Self>852     fn fixate(&self) -> Option<Self> {
853         unsafe {
854             let mut value = glib::Value::uninitialized();
855             let ret: bool = from_glib(gst_sys::gst_value_fixate(
856                 value.to_glib_none_mut().0,
857                 self.to_glib_none().0,
858             ));
859             if ret {
860                 Some(value)
861             } else {
862                 None
863             }
864         }
865     }
866 
is_fixed(&self) -> bool867     fn is_fixed(&self) -> bool {
868         unsafe { from_glib(gst_sys::gst_value_is_fixed(self.to_glib_none().0)) }
869     }
870 
is_subset(&self, superset: &Self) -> bool871     fn is_subset(&self, superset: &Self) -> bool {
872         unsafe {
873             from_glib(gst_sys::gst_value_is_subset(
874                 self.to_glib_none().0,
875                 superset.to_glib_none().0,
876             ))
877         }
878     }
879 
serialize(&self) -> Result<glib::GString, glib::BoolError>880     fn serialize(&self) -> Result<glib::GString, glib::BoolError> {
881         unsafe {
882             Option::<_>::from_glib_full(gst_sys::gst_value_serialize(self.to_glib_none().0))
883                 .ok_or_else(|| glib_bool_error!("Failed to serialize value"))
884         }
885     }
886 
deserialize<'a, T: Into<&'a str>>(s: T) -> Result<glib::Value, glib::BoolError>887     fn deserialize<'a, T: Into<&'a str>>(s: T) -> Result<glib::Value, glib::BoolError> {
888         assert_initialized_main_thread!();
889 
890         let s = s.into();
891 
892         unsafe {
893             let mut value = glib::Value::uninitialized();
894             let ret: bool = from_glib(gst_sys::gst_value_deserialize(
895                 value.to_glib_none_mut().0,
896                 s.to_glib_none().0,
897             ));
898             if ret {
899                 Ok(value)
900             } else {
901                 Err(glib_bool_error!("Failed to deserialize value"))
902             }
903         }
904     }
905 }
906 
907 #[cfg(test)]
908 mod tests {
909     #[test]
test_fraction()910     fn test_fraction() {
911         ::init().unwrap();
912 
913         let f1 = ::Fraction::new(1, 2);
914         let f2 = ::Fraction::new(2, 3);
915         let mut f3 = f1 * f2;
916         let f4 = f1 * f2;
917         f3 *= f2;
918         f3 *= f4;
919 
920         assert_eq!(f3, ::Fraction::new(2, 27));
921     }
922 }
923