1use glib::translate::{FromGlib, GlibNoneError, IntoGlib, OptionIntoGlib, TryFromGlib};
4
5use super::{
6 Format, FormattedValue, FormattedValueError, FormattedValueFullRange, FormattedValueIntrinsic,
7 FormattedValueNoneBuilder, GenericFormattedValue,
8};
9use crate::ffi;
10
11pub trait SpecificFormattedValue: FormattedValue {}
12
13pub trait SpecificFormattedValueFullRange: FormattedValueFullRange {}
14
15pub trait SpecificFormattedValueIntrinsic: TryFromGlib<i64> + FormattedValueIntrinsic {}
23
24#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
52pub struct Buffers(u64);
53impl Buffers {
54 #[doc(alias = "GST_BUFFER_OFFSET_NONE")]
55 pub const OFFSET_NONE: u64 = ffi::GST_BUFFER_OFFSET_NONE;
56 pub const MAX: Self = Self(Self::OFFSET_NONE - 1);
57}
58
59impl Buffers {
60 #[track_caller]
68 #[inline]
69 pub const fn from_u64(buffers: u64) -> Self {
70 if buffers == ffi::GST_BUFFER_OFFSET_NONE {
71 panic!("`Buffers` value out of range");
72 }
73
74 Buffers(buffers)
75 }
76
77 #[track_caller]
85 #[inline]
86 pub fn from_usize(buffers: usize) -> Self {
87 Buffers::from_u64(buffers.try_into().unwrap())
88 }
89}
90
91impl_common_ops_for_newtype_uint!(Buffers, u64);
92impl_signed_div_mul!(Buffers, u64);
93impl_signed_int_into_signed!(Buffers, u64);
94impl_format_value_traits!(Buffers, Buffers, Buffers, u64);
95option_glib_newtype_from_to!(Buffers, Buffers::OFFSET_NONE);
96glib_newtype_display!(Buffers, DisplayableOptionBuffers, Format::Buffers);
97
98impl TryFrom<Buffers> for usize {
99 type Error = std::num::TryFromIntError;
100
101 fn try_from(value: Buffers) -> Result<Self, Self::Error> {
102 value.0.try_into()
103 }
104}
105
106pub trait BuffersFormatConstructor {
110 fn buffers(self) -> Buffers;
113}
114
115impl BuffersFormatConstructor for u64 {
116 #[track_caller]
117 #[inline]
118 fn buffers(self) -> Buffers {
119 Buffers::from_u64(self)
120 }
121}
122
123#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
159pub struct Bytes(u64);
160impl Bytes {
161 #[allow(non_upper_case_globals)]
162 #[allow(non_upper_case_globals)]
165 pub const KiB: Self = Self(1024);
166 #[allow(non_upper_case_globals)]
169 pub const MiB: Self = Self(1024 * 1024);
170 #[allow(non_upper_case_globals)]
173 pub const GiB: Self = Self(1024 * 1024 * 1024);
174 pub const MAX: Self = Self(u64::MAX - 1);
175}
176
177impl Bytes {
178 #[track_caller]
186 #[inline]
187 pub const fn from_bytes(bytes: u64) -> Self {
188 Bytes::from_u64(bytes)
189 }
190
191 #[track_caller]
199 #[inline]
200 pub const fn from_kibibytes(kibibytes: u64) -> Self {
201 Bytes::from_u64(kibibytes * 1024)
202 }
203
204 #[track_caller]
212 #[inline]
213 pub const fn from_mebibytes(mebibytes: u64) -> Self {
214 Bytes::from_u64(mebibytes * 1024 * 1024)
215 }
216
217 #[track_caller]
225 #[inline]
226 pub const fn from_gibibytes(gibibytes: u64) -> Self {
227 Bytes::from_u64(gibibytes * 1024 * 1024 * 1024)
228 }
229
230 #[track_caller]
238 #[inline]
239 pub const fn from_u64(bytes: u64) -> Self {
240 if bytes == u64::MAX {
241 panic!("`Bytes` value out of range");
242 }
243
244 Bytes(bytes)
245 }
246
247 #[track_caller]
255 #[inline]
256 pub fn from_usize(bytes: usize) -> Self {
257 Bytes::from_u64(bytes.try_into().unwrap())
259 }
260}
261
262impl_common_ops_for_newtype_uint!(Bytes, u64);
263impl_signed_div_mul!(Bytes, u64);
264impl_signed_int_into_signed!(Bytes, u64);
265impl_format_value_traits!(Bytes, Bytes, Bytes, u64);
266option_glib_newtype_from_to!(Bytes, u64::MAX);
267glib_newtype_display!(Bytes, DisplayableOptionBytes, Format::Bytes);
268
269impl TryFrom<Bytes> for usize {
270 type Error = std::num::TryFromIntError;
271
272 fn try_from(value: Bytes) -> Result<Self, Self::Error> {
273 value.0.try_into()
274 }
275}
276
277pub trait BytesFormatConstructor {
285 fn bytes(self) -> Bytes;
288
289 fn kibibytes(self) -> Bytes;
292
293 fn mebibytes(self) -> Bytes;
296
297 fn gibibytes(self) -> Bytes;
300}
301
302impl BytesFormatConstructor for u64 {
303 #[track_caller]
304 #[inline]
305 fn bytes(self) -> Bytes {
306 Bytes::from_u64(self)
307 }
308
309 #[track_caller]
310 #[inline]
311 fn kibibytes(self) -> Bytes {
312 Bytes::from_u64(self * 1024)
313 }
314
315 #[track_caller]
316 #[inline]
317 fn mebibytes(self) -> Bytes {
318 Bytes::from_u64(self * 1024 * 1024)
319 }
320
321 #[track_caller]
322 #[inline]
323 fn gibibytes(self) -> Bytes {
324 Bytes::from_u64(self * 1024 * 1024 * 1024)
325 }
326}
327
328#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
356pub struct Default(u64);
357impl Default {
358 pub const MAX: Self = Self(u64::MAX - 1);
359}
360
361impl Default {
362 #[track_caller]
370 #[inline]
371 pub const fn from_u64(quantity: u64) -> Self {
372 if quantity == u64::MAX {
373 panic!("`Default` value out of range");
374 }
375
376 Default(quantity)
377 }
378
379 #[track_caller]
387 #[inline]
388 pub fn from_usize(quantity: usize) -> Self {
389 Default::from_u64(quantity.try_into().unwrap())
391 }
392}
393
394impl_common_ops_for_newtype_uint!(Default, u64);
395impl_signed_div_mul!(Default, u64);
396impl_signed_int_into_signed!(Default, u64);
397impl_format_value_traits!(Default, Default, Default, u64);
398option_glib_newtype_from_to!(Default, u64::MAX);
399glib_newtype_display!(Default, DisplayableOptionDefault, Format::Default);
400
401impl TryFrom<Default> for usize {
402 type Error = std::num::TryFromIntError;
403
404 fn try_from(value: Default) -> Result<Self, Self::Error> {
405 value.0.try_into()
406 }
407}
408
409pub trait DefaultFormatConstructor {
413 fn default_format(self) -> Default;
416}
417
418impl DefaultFormatConstructor for u64 {
419 #[track_caller]
420 #[inline]
421 fn default_format(self) -> Default {
422 Default::from_u64(self)
423 }
424}
425
426pub type Time = super::ClockTime;
427
428#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
457pub struct Percent(u32);
458impl Percent {
459 #[doc(alias = "GST_FORMAT_PERCENT_MAX")]
460 pub const MAX: Self = Self(ffi::GST_FORMAT_PERCENT_MAX as u32);
461 #[doc(alias = "GST_FORMAT_PERCENT_SCALE")]
462 pub const SCALE: Self = Self(ffi::GST_FORMAT_PERCENT_SCALE as u32);
463
464 #[track_caller]
471 #[inline]
472 pub const fn from_percent(percent: u32) -> Self {
473 if percent > 100 {
474 panic!("`Percent` value out of range");
475 }
476
477 Percent(ffi::GST_FORMAT_PERCENT_SCALE as u32 * percent)
478 }
479
480 #[track_caller]
487 #[inline]
488 pub const fn from_ppm(ppm: u32) -> Self {
489 if ppm > ffi::GST_FORMAT_PERCENT_MAX as u32 {
490 panic!("`Percent` ppm value out of range");
491 }
492
493 Percent(ppm)
494 }
495
496 #[track_caller]
503 #[inline]
504 pub fn from_ratio(ratio: f32) -> Self {
505 Percent::try_from(ratio).expect("`Percent` ratio out of range")
507 }
508
509 #[track_caller]
512 #[inline]
513 pub fn percent(&self) -> u32 {
514 self.0 / ffi::GST_FORMAT_PERCENT_SCALE as u32
515 }
516
517 #[track_caller]
520 #[inline]
521 pub fn ppm(&self) -> u32 {
522 self.0
523 }
524
525 #[track_caller]
528 #[inline]
529 pub fn ratio(&self) -> f32 {
530 self.0 as f32 / ffi::GST_FORMAT_PERCENT_MAX as f32
531 }
532}
533
534impl_common_ops_for_newtype_uint!(Percent, u32, one: ffi::GST_FORMAT_PERCENT_SCALE as u32);
535impl_signed_div_mul!(Percent, u32);
536impl_signed_int_into_signed!(Percent, u32);
537
538impl FormattedValue for Option<Percent> {
539 type FullRange = Option<Percent>;
540
541 #[inline]
542 fn default_format() -> Format {
543 Format::Percent
544 }
545
546 #[inline]
547 fn format(&self) -> Format {
548 Format::Percent
549 }
550
551 #[inline]
552 fn is_some(&self) -> bool {
553 Option::is_some(self)
554 }
555
556 #[inline]
557 unsafe fn into_raw_value(self) -> i64 {
558 self.map_or(-1, |v| v.0 as i64)
559 }
560}
561
562impl FormattedValueFullRange for Option<Percent> {
563 #[inline]
564 unsafe fn from_raw(format: Format, value: i64) -> Self {
565 unsafe {
566 debug_assert_eq!(format, Format::Percent);
567 Percent::try_from_glib(value).ok()
568 }
569 }
570}
571
572impl From<Option<Percent>> for GenericFormattedValue {
573 #[inline]
574 fn from(v: Option<Percent>) -> Self {
575 skip_assert_initialized!();
576 GenericFormattedValue::Percent(v)
577 }
578}
579
580impl From<Percent> for GenericFormattedValue {
581 #[inline]
582 fn from(v: Percent) -> Self {
583 skip_assert_initialized!();
584 GenericFormattedValue::Percent(Some(v))
585 }
586}
587
588impl FormattedValue for Percent {
589 type FullRange = Option<Percent>;
590
591 #[inline]
592 fn default_format() -> Format {
593 Format::Percent
594 }
595
596 #[inline]
597 fn format(&self) -> Format {
598 Format::Percent
599 }
600
601 #[inline]
602 fn is_some(&self) -> bool {
603 true
604 }
605
606 #[inline]
607 unsafe fn into_raw_value(self) -> i64 {
608 self.0 as i64
609 }
610}
611
612impl TryFrom<u64> for Percent {
613 type Error = GlibNoneError;
614
615 #[inline]
616 fn try_from(v: u64) -> Result<Percent, GlibNoneError> {
617 skip_assert_initialized!();
618 unsafe { Self::try_from_glib(v as i64) }
619 }
620}
621
622impl TryFromGlib<i64> for Percent {
623 type Error = GlibNoneError;
624 #[inline]
625 unsafe fn try_from_glib(value: i64) -> Result<Self, Self::Error> {
626 skip_assert_initialized!();
627 if value < 0 || value > ffi::GST_FORMAT_PERCENT_MAX {
628 Err(GlibNoneError)
629 } else {
630 Ok(Percent(value as u32))
631 }
632 }
633}
634
635impl TryFrom<u32> for Percent {
636 type Error = FormattedValueError;
637
638 #[inline]
639 fn try_from(value: u32) -> Result<Self, Self::Error> {
640 skip_assert_initialized!();
641 if value > ffi::GST_FORMAT_PERCENT_MAX as u32 {
642 Err(FormattedValueError(Format::Percent))
643 } else {
644 Ok(Percent(value))
645 }
646 }
647}
648
649impl TryFrom<GenericFormattedValue> for Option<Percent> {
650 type Error = FormattedValueError;
651
652 #[inline]
653 fn try_from(v: GenericFormattedValue) -> Result<Option<Percent>, Self::Error> {
654 skip_assert_initialized!();
655 if let GenericFormattedValue::Percent(v) = v {
656 Ok(v)
657 } else {
658 Err(FormattedValueError(v.format()))
659 }
660 }
661}
662
663impl FormattedValueIntrinsic for Percent {}
664impl SpecificFormattedValue for Option<Percent> {}
665impl SpecificFormattedValueFullRange for Option<Percent> {}
666impl SpecificFormattedValueIntrinsic for Percent {}
667impl FormattedValueNoneBuilder for Option<Percent> {
668 #[inline]
669 fn none() -> Option<Percent> {
670 None
671 }
672}
673
674#[derive(Clone, Copy, Debug, PartialEq, Eq, thiserror::Error)]
675#[error("value out of range")]
676pub struct TryPercentFromFloatError(());
677
678impl TryFrom<f64> for Percent {
679 type Error = TryPercentFromFloatError;
680
681 #[inline]
682 fn try_from(v: f64) -> Result<Self, Self::Error> {
683 skip_assert_initialized!();
684 if v < 0.0 || v > 1.0 {
685 Err(TryPercentFromFloatError(()))
686 } else {
687 Ok(Percent(
688 (v * ffi::GST_FORMAT_PERCENT_MAX as f64).round() as u32
689 ))
690 }
691 }
692}
693
694impl TryFrom<f32> for Percent {
695 type Error = TryPercentFromFloatError;
696
697 #[inline]
698 fn try_from(v: f32) -> Result<Self, Self::Error> {
699 skip_assert_initialized!();
700 if v < 0.0 || v > 1.0 {
701 Err(TryPercentFromFloatError(()))
702 } else {
703 Ok(Percent(
704 (v * ffi::GST_FORMAT_PERCENT_MAX as f32).round() as u32
705 ))
706 }
707 }
708}
709
710pub trait PercentFormatIntegerConstructor {
714 fn percent(self) -> Percent;
717
718 fn ppm(self) -> Percent;
721}
722
723impl PercentFormatIntegerConstructor for u32 {
724 #[track_caller]
725 #[inline]
726 fn percent(self) -> Percent {
727 Percent::from_percent(self)
728 }
729
730 #[track_caller]
731 #[inline]
732 fn ppm(self) -> Percent {
733 Percent::from_ppm(self)
734 }
735}
736
737pub trait PercentFormatFloatConstructor {
741 fn percent_ratio(self) -> Percent;
744}
745
746impl PercentFormatFloatConstructor for f32 {
747 #[track_caller]
748 #[inline]
749 fn percent_ratio(self) -> Percent {
750 Percent::try_from(self).unwrap()
751 }
752}
753
754impl std::fmt::Display for Percent {
755 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
756 std::fmt::Display::fmt(&(self.0 as f32 / (*Percent::SCALE) as f32), f)?;
757 f.write_str(" %")
758 }
759}
760
761impl crate::utils::Displayable for Percent {
762 type DisplayImpl = Self;
763 fn display(self) -> Self {
764 self
765 }
766}
767pub struct DisplayableOptionPercent(Option<Percent>);
768
769impl std::fmt::Display for DisplayableOptionPercent {
770 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
771 if let Some(val) = self.0.as_ref() {
772 std::fmt::Display::fmt(val, f)
773 } else {
774 f.write_str("undef. %")
775 }
776 }
777}
778
779impl crate::utils::Displayable for Option<Percent> {
780 type DisplayImpl = DisplayableOptionPercent;
781 fn display(self) -> Self::DisplayImpl {
782 DisplayableOptionPercent(self)
783 }
784}