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 debug_assert_eq!(format, Format::Percent);
566 Percent::try_from_glib(value).ok()
567 }
568}
569
570impl From<Option<Percent>> for GenericFormattedValue {
571 #[inline]
572 fn from(v: Option<Percent>) -> Self {
573 skip_assert_initialized!();
574 GenericFormattedValue::Percent(v)
575 }
576}
577
578impl From<Percent> for GenericFormattedValue {
579 #[inline]
580 fn from(v: Percent) -> Self {
581 skip_assert_initialized!();
582 GenericFormattedValue::Percent(Some(v))
583 }
584}
585
586impl FormattedValue for Percent {
587 type FullRange = Option<Percent>;
588
589 #[inline]
590 fn default_format() -> Format {
591 Format::Percent
592 }
593
594 #[inline]
595 fn format(&self) -> Format {
596 Format::Percent
597 }
598
599 #[inline]
600 fn is_some(&self) -> bool {
601 true
602 }
603
604 #[inline]
605 unsafe fn into_raw_value(self) -> i64 {
606 self.0 as i64
607 }
608}
609
610impl TryFrom<u64> for Percent {
611 type Error = GlibNoneError;
612
613 #[inline]
614 fn try_from(v: u64) -> Result<Percent, GlibNoneError> {
615 skip_assert_initialized!();
616 unsafe { Self::try_from_glib(v as i64) }
617 }
618}
619
620impl TryFromGlib<i64> for Percent {
621 type Error = GlibNoneError;
622 #[inline]
623 unsafe fn try_from_glib(value: i64) -> Result<Self, Self::Error> {
624 skip_assert_initialized!();
625 if value < 0 || value > ffi::GST_FORMAT_PERCENT_MAX {
626 Err(GlibNoneError)
627 } else {
628 Ok(Percent(value as u32))
629 }
630 }
631}
632
633impl TryFrom<u32> for Percent {
634 type Error = FormattedValueError;
635
636 #[inline]
637 fn try_from(value: u32) -> Result<Self, Self::Error> {
638 skip_assert_initialized!();
639 if value > ffi::GST_FORMAT_PERCENT_MAX as u32 {
640 Err(FormattedValueError(Format::Percent))
641 } else {
642 Ok(Percent(value))
643 }
644 }
645}
646
647impl TryFrom<GenericFormattedValue> for Option<Percent> {
648 type Error = FormattedValueError;
649
650 #[inline]
651 fn try_from(v: GenericFormattedValue) -> Result<Option<Percent>, Self::Error> {
652 skip_assert_initialized!();
653 if let GenericFormattedValue::Percent(v) = v {
654 Ok(v)
655 } else {
656 Err(FormattedValueError(v.format()))
657 }
658 }
659}
660
661impl FormattedValueIntrinsic for Percent {}
662impl SpecificFormattedValue for Option<Percent> {}
663impl SpecificFormattedValueFullRange for Option<Percent> {}
664impl SpecificFormattedValueIntrinsic for Percent {}
665impl FormattedValueNoneBuilder for Option<Percent> {
666 #[inline]
667 fn none() -> Option<Percent> {
668 None
669 }
670}
671
672#[derive(Clone, Copy, Debug, PartialEq, Eq, thiserror::Error)]
673#[error("value out of range")]
674pub struct TryPercentFromFloatError(());
675
676impl TryFrom<f64> for Percent {
677 type Error = TryPercentFromFloatError;
678
679 #[inline]
680 fn try_from(v: f64) -> Result<Self, Self::Error> {
681 skip_assert_initialized!();
682 if v < 0.0 || v > 1.0 {
683 Err(TryPercentFromFloatError(()))
684 } else {
685 Ok(Percent(
686 (v * ffi::GST_FORMAT_PERCENT_MAX as f64).round() as u32
687 ))
688 }
689 }
690}
691
692impl TryFrom<f32> for Percent {
693 type Error = TryPercentFromFloatError;
694
695 #[inline]
696 fn try_from(v: f32) -> Result<Self, Self::Error> {
697 skip_assert_initialized!();
698 if v < 0.0 || v > 1.0 {
699 Err(TryPercentFromFloatError(()))
700 } else {
701 Ok(Percent(
702 (v * ffi::GST_FORMAT_PERCENT_MAX as f32).round() as u32
703 ))
704 }
705 }
706}
707
708pub trait PercentFormatIntegerConstructor {
712 fn percent(self) -> Percent;
715
716 fn ppm(self) -> Percent;
719}
720
721impl PercentFormatIntegerConstructor for u32 {
722 #[track_caller]
723 #[inline]
724 fn percent(self) -> Percent {
725 Percent::from_percent(self)
726 }
727
728 #[track_caller]
729 #[inline]
730 fn ppm(self) -> Percent {
731 Percent::from_ppm(self)
732 }
733}
734
735pub trait PercentFormatFloatConstructor {
739 fn percent_ratio(self) -> Percent;
742}
743
744impl PercentFormatFloatConstructor for f32 {
745 #[track_caller]
746 #[inline]
747 fn percent_ratio(self) -> Percent {
748 Percent::try_from(self).unwrap()
749 }
750}
751
752impl std::fmt::Display for Percent {
753 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
754 std::fmt::Display::fmt(&(self.0 as f32 / (*Percent::SCALE) as f32), f)?;
755 f.write_str(" %")
756 }
757}
758
759impl crate::utils::Displayable for Percent {
760 type DisplayImpl = Self;
761 fn display(self) -> Self {
762 self
763 }
764}
765pub struct DisplayableOptionPercent(Option<Percent>);
766
767impl std::fmt::Display for DisplayableOptionPercent {
768 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
769 if let Some(val) = self.0.as_ref() {
770 std::fmt::Display::fmt(val, f)
771 } else {
772 f.write_str("undef. %")
773 }
774 }
775}
776
777impl crate::utils::Displayable for Option<Percent> {
778 type DisplayImpl = DisplayableOptionPercent;
779 fn display(self) -> Self::DisplayImpl {
780 DisplayableOptionPercent(self)
781 }
782}