forked from mirrors/gstreamer-rs
format/specific: don't expose inner as pub
... users would be able to bypass the range checks and build a defined Rust value which would be interpreted as `None` in C code. Added format module examples for formatted values constructions.
This commit is contained in:
parent
f6336b1be3
commit
08551bb1bc
9 changed files with 142 additions and 60 deletions
|
@ -294,20 +294,19 @@ mod tests {
|
||||||
|
|
||||||
let mut buffer = gst::Buffer::with_size(1024).unwrap();
|
let mut buffer = gst::Buffer::with_size(1024).unwrap();
|
||||||
|
|
||||||
|
let start = gst::format::Default::ONE;
|
||||||
|
let stop = 2 * gst::format::Default::ONE;
|
||||||
|
|
||||||
{
|
{
|
||||||
let cmeta = AudioClippingMeta::add(
|
let cmeta = AudioClippingMeta::add(buffer.get_mut().unwrap(), start, stop);
|
||||||
buffer.get_mut().unwrap(),
|
assert_eq!(cmeta.start().try_into(), Ok(Some(start)));
|
||||||
gst::format::Default(1),
|
assert_eq!(cmeta.end().try_into(), Ok(Some(stop)));
|
||||||
gst::format::Default(2),
|
|
||||||
);
|
|
||||||
assert_eq!(cmeta.start().try_into(), Ok(Some(gst::format::Default(1))));
|
|
||||||
assert_eq!(cmeta.end().try_into(), Ok(Some(gst::format::Default(2))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let cmeta = buffer.meta::<AudioClippingMeta>().unwrap();
|
let cmeta = buffer.meta::<AudioClippingMeta>().unwrap();
|
||||||
assert_eq!(cmeta.start().try_into(), Ok(Some(gst::format::Default(1))));
|
assert_eq!(cmeta.start().try_into(), Ok(Some(start)));
|
||||||
assert_eq!(cmeta.end().try_into(), Ok(Some(gst::format::Default(2))));
|
assert_eq!(cmeta.end().try_into(), Ok(Some(stop)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ use super::{
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)]
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)]
|
||||||
pub struct ClockTime(pub(crate) u64);
|
pub struct ClockTime(u64);
|
||||||
|
|
||||||
impl ClockTime {
|
impl ClockTime {
|
||||||
#[doc(alias = "GST_SECOND")]
|
#[doc(alias = "GST_SECOND")]
|
||||||
|
|
|
@ -7,14 +7,20 @@ use crate::ClockTime;
|
||||||
|
|
||||||
impl Serialize for ClockTime {
|
impl Serialize for ClockTime {
|
||||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||||
self.0.serialize(serializer)
|
use std::ops::Deref;
|
||||||
|
self.deref().serialize(serializer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for ClockTime {
|
impl<'de> Deserialize<'de> for ClockTime {
|
||||||
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
u64::deserialize(deserializer).map(ClockTime::from_nseconds)
|
u64::deserialize(deserializer).and_then(|value| {
|
||||||
|
ClockTime::try_from(value).map_err(|_| {
|
||||||
|
use serde::de::{Error, Unexpected};
|
||||||
|
D::Error::invalid_value(Unexpected::Unsigned(value), &"valid `ClockTime`")
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ mod tests {
|
||||||
let res = serde_json::to_string(&value).unwrap();
|
let res = serde_json::to_string(&value).unwrap();
|
||||||
assert_eq!("{\"Undefined\":42}".to_owned(), res);
|
assert_eq!("{\"Undefined\":42}".to_owned(), res);
|
||||||
|
|
||||||
let value = GenericFormattedValue::from(Default(42));
|
let value = GenericFormattedValue::from(42 * Default::ONE);
|
||||||
let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
|
let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
|
||||||
assert_eq!(Ok("Default(Some(42))".to_owned()), res);
|
assert_eq!(Ok("Default(Some(42))".to_owned()), res);
|
||||||
let res = serde_json::to_string(&value).unwrap();
|
let res = serde_json::to_string(&value).unwrap();
|
||||||
|
@ -87,7 +87,7 @@ mod tests {
|
||||||
let res = serde_json::to_string(&value).unwrap();
|
let res = serde_json::to_string(&value).unwrap();
|
||||||
assert_eq!("{\"Default\":null}".to_owned(), res);
|
assert_eq!("{\"Default\":null}".to_owned(), res);
|
||||||
|
|
||||||
let value = GenericFormattedValue::from(Bytes(42));
|
let value = GenericFormattedValue::from(42 * Bytes::ONE);
|
||||||
let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
|
let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
|
||||||
assert_eq!(Ok("Bytes(Some(42))".to_owned()), res);
|
assert_eq!(Ok("Bytes(Some(42))".to_owned()), res);
|
||||||
let res = serde_json::to_string(&value).unwrap();
|
let res = serde_json::to_string(&value).unwrap();
|
||||||
|
@ -99,19 +99,21 @@ mod tests {
|
||||||
let res = serde_json::to_string(&value).unwrap();
|
let res = serde_json::to_string(&value).unwrap();
|
||||||
assert_eq!("{\"Time\":42123456789}".to_owned(), res);
|
assert_eq!("{\"Time\":42123456789}".to_owned(), res);
|
||||||
|
|
||||||
let value = GenericFormattedValue::from(Buffers(42));
|
let value = GenericFormattedValue::from(42 * Buffers::ONE);
|
||||||
let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
|
let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
|
||||||
assert_eq!(Ok("Buffers(Some(42))".to_owned()), res);
|
assert_eq!(Ok("Buffers(Some(42))".to_owned()), res);
|
||||||
let res = serde_json::to_string(&value).unwrap();
|
let res = serde_json::to_string(&value).unwrap();
|
||||||
assert_eq!("{\"Buffers\":42}".to_owned(), res);
|
assert_eq!("{\"Buffers\":42}".to_owned(), res);
|
||||||
|
|
||||||
let value = GenericFormattedValue::from(Percent::try_from(0.42).unwrap());
|
let percent = Percent::try_from(0.42).unwrap();
|
||||||
|
let value = GenericFormattedValue::from(percent);
|
||||||
let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
|
let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
|
||||||
assert_eq!(Ok("Percent(Some(4200))".to_owned()), res);
|
assert_eq!(Ok("Percent(Some(4200))".to_owned()), res);
|
||||||
let res = serde_json::to_string(&value).unwrap();
|
let res = serde_json::to_string(&value).unwrap();
|
||||||
assert_eq!("{\"Percent\":4200}".to_owned(), res);
|
assert_eq!("{\"Percent\":4200}".to_owned(), res);
|
||||||
|
|
||||||
let value = GenericFormattedValue::Other(Format::Percent, Other::try_from(42).ok());
|
let other = Other::try_from(42).ok();
|
||||||
|
let value = GenericFormattedValue::Other(Format::Percent, other);
|
||||||
let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
|
let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
|
||||||
assert_eq!(Ok("Other(Percent, Some(42))".to_owned()), res);
|
assert_eq!(Ok("Other(Percent, Some(42))".to_owned()), res);
|
||||||
let res = serde_json::to_string(&value).unwrap();
|
let res = serde_json::to_string(&value).unwrap();
|
||||||
|
@ -130,14 +132,14 @@ mod tests {
|
||||||
|
|
||||||
let value_ron = "Default(Some(42))";
|
let value_ron = "Default(Some(42))";
|
||||||
let value_de: GenericFormattedValue = ron::de::from_str(value_ron).unwrap();
|
let value_de: GenericFormattedValue = ron::de::from_str(value_ron).unwrap();
|
||||||
assert_eq!(value_de, GenericFormattedValue::from(Default(42)));
|
assert_eq!(value_de, GenericFormattedValue::from(42 * Default::ONE));
|
||||||
|
|
||||||
let value_json = "{\"Default\":42}";
|
let value_json = "{\"Default\":42}";
|
||||||
let value_de: GenericFormattedValue = serde_json::from_str(value_json).unwrap();
|
let value_de: GenericFormattedValue = serde_json::from_str(value_json).unwrap();
|
||||||
assert_eq!(value_de, GenericFormattedValue::from(Default(42)));
|
assert_eq!(value_de, GenericFormattedValue::from(42 * Default::ONE));
|
||||||
|
|
||||||
let value_ron = "Other(Percent, Some(42))";
|
let value_ron = "Other(Percent, Some(42))";
|
||||||
let gfv_value = GenericFormattedValue::Other(Format::Percent, Other::try_from(42).ok());
|
let gfv_value = GenericFormattedValue::Other(Format::Percent, Some(42 * Other::ONE));
|
||||||
|
|
||||||
let value_de: GenericFormattedValue = ron::de::from_str(value_ron).unwrap();
|
let value_de: GenericFormattedValue = ron::de::from_str(value_ron).unwrap();
|
||||||
assert_eq!(value_de, gfv_value);
|
assert_eq!(value_de, gfv_value);
|
||||||
|
@ -159,16 +161,14 @@ mod tests {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
test_roundrip!(GenericFormattedValue::Undefined(Undefined::from(42)));
|
test_roundrip!(GenericFormattedValue::Undefined(Undefined(42)));
|
||||||
test_roundrip!(GenericFormattedValue::from(Default(42)));
|
test_roundrip!(GenericFormattedValue::from(42 * Default::ONE));
|
||||||
test_roundrip!(GenericFormattedValue::from(Bytes(42)));
|
test_roundrip!(GenericFormattedValue::from(42 * Bytes::ONE));
|
||||||
test_roundrip!(GenericFormattedValue::from(ClockTime::from_nseconds(
|
test_roundrip!(GenericFormattedValue::from(ClockTime::from_nseconds(
|
||||||
42_123_456_789
|
42_123_456_789
|
||||||
)));
|
)));
|
||||||
test_roundrip!(GenericFormattedValue::from(Buffers(42)));
|
test_roundrip!(GenericFormattedValue::from(42 * Buffers::ONE));
|
||||||
test_roundrip!(GenericFormattedValue::from(
|
test_roundrip!(GenericFormattedValue::from(42 * Percent::ONE));
|
||||||
Percent::try_from(0.42).unwrap()
|
|
||||||
));
|
|
||||||
let gfv_value = GenericFormattedValue::Other(Format::Percent, Other::try_from(42).ok());
|
let gfv_value = GenericFormattedValue::Other(Format::Percent, Other::try_from(42).ok());
|
||||||
test_roundrip!(gfv_value);
|
test_roundrip!(gfv_value);
|
||||||
test_roundrip!(GenericFormattedValue::new(Format::__Unknown(7), 42));
|
test_roundrip!(GenericFormattedValue::new(Format::__Unknown(7), 42));
|
||||||
|
|
|
@ -229,9 +229,16 @@ macro_rules! impl_unsigned_int_into_signed(
|
||||||
|
|
||||||
macro_rules! impl_common_ops_for_newtype_uint(
|
macro_rules! impl_common_ops_for_newtype_uint(
|
||||||
($typ:ty, $inner:ty) => {
|
($typ:ty, $inner:ty) => {
|
||||||
|
impl_common_ops_for_newtype_uint!($typ, $inner, one: 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
($typ:ty, $inner:ty, one: $one:expr$(,)?) => {
|
||||||
impl $typ {
|
impl $typ {
|
||||||
pub const ZERO: Self = Self(0);
|
pub const ZERO: Self = Self(0);
|
||||||
pub const NONE: Option<Self> = None;
|
pub const NONE: Option<Self> = None;
|
||||||
|
// rustdoc-stripper-ignore-next
|
||||||
|
/// The unitary value.
|
||||||
|
pub const ONE: Self = Self($one);
|
||||||
|
|
||||||
pub const MAX_SIGNED: crate::Signed::<$typ> = crate::Signed::Positive(Self::MAX);
|
pub const MAX_SIGNED: crate::Signed::<$typ> = crate::Signed::Positive(Self::MAX);
|
||||||
pub const MIN_SIGNED: crate::Signed::<$typ> = crate::Signed::Negative(Self::MAX);
|
pub const MIN_SIGNED: crate::Signed::<$typ> = crate::Signed::Negative(Self::MAX);
|
||||||
|
@ -1501,22 +1508,30 @@ macro_rules! impl_format_value_traits(
|
||||||
);
|
);
|
||||||
|
|
||||||
macro_rules! option_glib_newtype_from_to {
|
macro_rules! option_glib_newtype_from_to {
|
||||||
($typ_:ident, $none_value:expr) => {
|
($typ:ident, $none_value:expr) => {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
impl IntoGlib for $typ_ {
|
impl IntoGlib for $typ {
|
||||||
type GlibType = u64;
|
type GlibType = u64;
|
||||||
fn into_glib(self) -> u64 {
|
fn into_glib(self) -> u64 {
|
||||||
|
assert_ne!(
|
||||||
|
self.0, $none_value,
|
||||||
|
concat!(
|
||||||
|
"attempt to build a `None` glib variant",
|
||||||
|
"from a non-`Option` type ",
|
||||||
|
stringify!($typ),
|
||||||
|
),
|
||||||
|
);
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
impl OptionIntoGlib for $typ_ {
|
impl OptionIntoGlib for $typ {
|
||||||
const GLIB_NONE: u64 = $none_value;
|
const GLIB_NONE: u64 = $none_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
impl TryFromGlib<u64> for $typ_ {
|
impl TryFromGlib<u64> for $typ {
|
||||||
type Error = GlibNoneError;
|
type Error = GlibNoneError;
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn try_from_glib(val: u64) -> Result<Self, GlibNoneError> {
|
unsafe fn try_from_glib(val: u64) -> Result<Self, GlibNoneError> {
|
||||||
|
@ -1525,7 +1540,7 @@ macro_rules! option_glib_newtype_from_to {
|
||||||
return Err(GlibNoneError);
|
return Err(GlibNoneError);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok($typ_(val))
|
Ok($typ(val))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,7 +17,8 @@
|
||||||
//! Specific formatted values are also guaranteed to always represent a valid value.
|
//! Specific formatted values are also guaranteed to always represent a valid value.
|
||||||
//! For instance:
|
//! For instance:
|
||||||
//!
|
//!
|
||||||
//! - [`Percent`] only allows values in the range [0, 1_000_000].
|
//! - [`Percent`] only allows values in the integer range [0, 1_000_000] or
|
||||||
|
//! float range [0.0, 1.0].
|
||||||
//! - [`ClockTime`] can use all `u64` values except `u64::MAX` which is reserved by
|
//! - [`ClockTime`] can use all `u64` values except `u64::MAX` which is reserved by
|
||||||
//! the C constant `GST_CLOCK_TIME_NONE`.
|
//! the C constant `GST_CLOCK_TIME_NONE`.
|
||||||
//!
|
//!
|
||||||
|
@ -60,6 +61,52 @@
|
||||||
//! assert_eq!(start.format(), gst::Format::Time);
|
//! assert_eq!(start.format(), gst::Format::Time);
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
|
//! ### Building a specific formatted value
|
||||||
|
//!
|
||||||
|
//! ```
|
||||||
|
//! # use gstreamer as gst;
|
||||||
|
//! use gst::format::{Buffers, Bytes, ClockTime, Default, Percent};
|
||||||
|
//!
|
||||||
|
//! // Specific formatted values implement the faillible `try_from` constructor:
|
||||||
|
//! let default = Default::try_from(42).unwrap();
|
||||||
|
//! assert_eq!(*default, 42);
|
||||||
|
//! assert_eq!(Default::try_from(42), Ok(default));
|
||||||
|
//! assert_eq!(Default::try_from(42).ok(), Some(default));
|
||||||
|
//!
|
||||||
|
//! // `ClockTime` provides specific constructors:
|
||||||
|
//! let time = ClockTime::from_nseconds(45_834_908_569_837);
|
||||||
|
//! let time = ClockTime::from_seconds(20);
|
||||||
|
//!
|
||||||
|
//! // This can be convenient:
|
||||||
|
//! assert_eq!(
|
||||||
|
//! 20 * ClockTime::MSECOND,
|
||||||
|
//! ClockTime::from_nseconds(20_000_000),
|
||||||
|
//! );
|
||||||
|
//! assert_eq!(
|
||||||
|
//! 40 * ClockTime::SECOND,
|
||||||
|
//! ClockTime::from_nseconds(40_000_000_000),
|
||||||
|
//! );
|
||||||
|
//!
|
||||||
|
//! // Specific formatted values provide the `ONE` value:
|
||||||
|
//! assert_eq!(*(128 * Buffers::ONE), 128);
|
||||||
|
//!
|
||||||
|
//! // `ZERO` and `NONE` can also come in handy sometimes:
|
||||||
|
//! assert_eq!(*Buffers::ZERO, 0);
|
||||||
|
//! assert!(ClockTime::NONE.is_none());
|
||||||
|
//!
|
||||||
|
//! // `Bytes` also comes with usual multipliers:
|
||||||
|
//! assert_eq!(*(512 * Bytes::K), 512 * 1024);
|
||||||
|
//! assert_eq!(*(8 * Bytes::M), 8 * 1024 * 1024);
|
||||||
|
//! assert_eq!(*(4 * Bytes::G), 4 * 1024 * 1024 * 1024);
|
||||||
|
//!
|
||||||
|
//! // `Percent` can be built from a float:
|
||||||
|
//! let a_quarter = Percent::try_from(0.25).unwrap();
|
||||||
|
//! // `Percent` has `SCALE` which represents 100%:
|
||||||
|
//! assert_eq!(Percent::SCALE / 4, a_quarter);
|
||||||
|
//! // ... and `ONE` which is 1%:
|
||||||
|
//! assert_eq!(25 * Percent::ONE, a_quarter);
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
//! ### Displaying a formatted value
|
//! ### Displaying a formatted value
|
||||||
//!
|
//!
|
||||||
//! Formatted values implement the [`Display`] trait which allows getting
|
//! Formatted values implement the [`Display`] trait which allows getting
|
||||||
|
@ -334,7 +381,7 @@
|
||||||
//! // Signed formatted values implement the `MulDiv` trait:
|
//! // Signed formatted values implement the `MulDiv` trait:
|
||||||
//! # use gst::prelude::MulDiv;
|
//! # use gst::prelude::MulDiv;
|
||||||
//! # let rate = 48000u64;
|
//! # let rate = 48000u64;
|
||||||
//! let samples = gst::format::Default(1024).into_negative();
|
//! let samples = (1024 * gst::format::Default::ONE).into_negative();
|
||||||
//! let duration = samples
|
//! let duration = samples
|
||||||
//! .mul_div_round(*gst::ClockTime::SECOND, rate)
|
//! .mul_div_round(*gst::ClockTime::SECOND, rate)
|
||||||
//! .map(|signed_default| {
|
//! .map(|signed_default| {
|
||||||
|
@ -383,7 +430,7 @@
|
||||||
//! # use gstreamer as gst;
|
//! # use gstreamer as gst;
|
||||||
//! # use gst::prelude::{Displayable, ElementExtManual};
|
//! # use gst::prelude::{Displayable, ElementExtManual};
|
||||||
//! # gst::init();
|
//! # gst::init();
|
||||||
//! # let event = gst::event::SegmentDone::new(gst::format::Buffers(512));
|
//! # let event = gst::event::SegmentDone::new(512 * gst::format::Buffers::ONE);
|
||||||
//! if let gst::EventView::SegmentDone(seg_done_evt) = event.view() {
|
//! if let gst::EventView::SegmentDone(seg_done_evt) = event.view() {
|
||||||
//! use gst::GenericFormattedValue::*;
|
//! use gst::GenericFormattedValue::*;
|
||||||
//! match seg_done_evt.get() {
|
//! match seg_done_evt.get() {
|
||||||
|
@ -592,11 +639,11 @@ mod tests {
|
||||||
fn incompatible() {
|
fn incompatible() {
|
||||||
with_compatible_formats(
|
with_compatible_formats(
|
||||||
ClockTime::ZERO,
|
ClockTime::ZERO,
|
||||||
GenericFormattedValue::Buffers(Some(Buffers(42))),
|
GenericFormattedValue::Buffers(Some(42 * Buffers::ONE)),
|
||||||
)
|
)
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
with_compatible_formats(
|
with_compatible_formats(
|
||||||
GenericFormattedValue::Buffers(Some(Buffers(42))),
|
GenericFormattedValue::Buffers(Some(42 * Buffers::ONE)),
|
||||||
ClockTime::NONE,
|
ClockTime::NONE,
|
||||||
)
|
)
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
@ -744,20 +791,18 @@ mod tests {
|
||||||
assert!(signed.positive().is_none());
|
assert!(signed.positive().is_none());
|
||||||
assert_eq!(signed.signum(), -1);
|
assert_eq!(signed.signum(), -1);
|
||||||
|
|
||||||
let def = Default(1);
|
let signed = Default::ONE.into_positive();
|
||||||
|
assert_eq!(signed, Signed::Positive(Default::ONE));
|
||||||
let signed = def.into_positive();
|
|
||||||
assert_eq!(signed, Signed::Positive(def));
|
|
||||||
assert!(signed.is_positive());
|
assert!(signed.is_positive());
|
||||||
assert_eq!(signed.positive(), Some(def));
|
assert_eq!(signed.positive(), Some(Default::ONE));
|
||||||
assert!(!signed.is_negative());
|
assert!(!signed.is_negative());
|
||||||
assert!(signed.negative().is_none());
|
assert!(signed.negative().is_none());
|
||||||
assert_eq!(signed.signum(), 1);
|
assert_eq!(signed.signum(), 1);
|
||||||
|
|
||||||
let signed = def.into_negative();
|
let signed = Default::ONE.into_negative();
|
||||||
assert_eq!(signed, Signed::Negative(def));
|
assert_eq!(signed, Signed::Negative(Default::ONE));
|
||||||
assert!(signed.is_negative());
|
assert!(signed.is_negative());
|
||||||
assert_eq!(signed.negative(), Some(def));
|
assert_eq!(signed.negative(), Some(Default::ONE));
|
||||||
assert!(!signed.is_positive());
|
assert!(!signed.is_positive());
|
||||||
assert!(signed.positive().is_none());
|
assert!(signed.positive().is_none());
|
||||||
assert_eq!(signed.signum(), -1);
|
assert_eq!(signed.signum(), -1);
|
||||||
|
@ -855,14 +900,14 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn display_new_types() {
|
fn display_new_types() {
|
||||||
let bytes = Bytes(42);
|
let bytes = 42 * Bytes::ONE;
|
||||||
assert_eq!(&format!("{bytes}"), "42 bytes");
|
assert_eq!(&format!("{bytes}"), "42 bytes");
|
||||||
assert_eq!(&format!("{}", bytes.display()), "42 bytes");
|
assert_eq!(&format!("{}", bytes.display()), "42 bytes");
|
||||||
|
|
||||||
assert_eq!(&format!("{}", Some(bytes).display()), "42 bytes");
|
assert_eq!(&format!("{}", Some(bytes).display()), "42 bytes");
|
||||||
assert_eq!(&format!("{}", Bytes::NONE.display()), "undef. bytes");
|
assert_eq!(&format!("{}", Bytes::NONE.display()), "undef. bytes");
|
||||||
|
|
||||||
let gv_1 = GenericFormattedValue::Percent(Percent::try_from(0.42).ok());
|
let gv_1 = GenericFormattedValue::Percent(Some(42 * Percent::ONE));
|
||||||
assert_eq!(&format!("{gv_1}"), "42 %");
|
assert_eq!(&format!("{gv_1}"), "42 %");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&format!("{}", GenericFormattedValue::Percent(None)),
|
&format!("{}", GenericFormattedValue::Percent(None)),
|
||||||
|
@ -890,24 +935,25 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn display_signed() {
|
fn display_signed() {
|
||||||
let p_bytes = Bytes(42).into_positive();
|
let bytes_42 = 42 * Bytes::ONE;
|
||||||
|
let p_bytes = bytes_42.into_positive();
|
||||||
assert_eq!(&format!("{p_bytes}"), "+42 bytes");
|
assert_eq!(&format!("{p_bytes}"), "+42 bytes");
|
||||||
assert_eq!(&format!("{}", p_bytes.display()), "+42 bytes");
|
assert_eq!(&format!("{}", p_bytes.display()), "+42 bytes");
|
||||||
|
|
||||||
let some_p_bytes = Some(p_bytes);
|
let some_p_bytes = Some(p_bytes);
|
||||||
assert_eq!(&format!("{}", some_p_bytes.display()), "+42 bytes");
|
assert_eq!(&format!("{}", some_p_bytes.display()), "+42 bytes");
|
||||||
|
|
||||||
let p_some_bytes = Signed::Positive(Some(Bytes(42)));
|
let p_some_bytes = Signed::Positive(Some(bytes_42));
|
||||||
assert_eq!(&format!("{}", p_some_bytes.display()), "+42 bytes");
|
assert_eq!(&format!("{}", p_some_bytes.display()), "+42 bytes");
|
||||||
|
|
||||||
let n_bytes = Bytes(42).into_negative();
|
let n_bytes = bytes_42.into_negative();
|
||||||
assert_eq!(&format!("{n_bytes}"), "-42 bytes");
|
assert_eq!(&format!("{n_bytes}"), "-42 bytes");
|
||||||
assert_eq!(&format!("{}", n_bytes.display()), "-42 bytes");
|
assert_eq!(&format!("{}", n_bytes.display()), "-42 bytes");
|
||||||
|
|
||||||
let some_n_bytes = Some(n_bytes);
|
let some_n_bytes = Some(n_bytes);
|
||||||
assert_eq!(&format!("{}", some_n_bytes.display()), "-42 bytes");
|
assert_eq!(&format!("{}", some_n_bytes.display()), "-42 bytes");
|
||||||
|
|
||||||
let n_some_bytes = Signed::Negative(Some(Bytes(42)));
|
let n_some_bytes = Signed::Negative(Some(bytes_42));
|
||||||
assert_eq!(&format!("{}", n_some_bytes.display()), "-42 bytes");
|
assert_eq!(&format!("{}", n_some_bytes.display()), "-42 bytes");
|
||||||
|
|
||||||
let p_none_bytes = Signed::Positive(Bytes::NONE);
|
let p_none_bytes = Signed::Positive(Bytes::NONE);
|
||||||
|
|
|
@ -21,7 +21,7 @@ pub trait SpecificFormattedValueFullRange: FormattedValueFullRange {}
|
||||||
pub trait SpecificFormattedValueIntrinsic: TryFromGlib<i64> + FormattedValueIntrinsic {}
|
pub trait SpecificFormattedValueIntrinsic: TryFromGlib<i64> + FormattedValueIntrinsic {}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
|
||||||
pub struct Buffers(pub u64);
|
pub struct Buffers(u64);
|
||||||
impl Buffers {
|
impl Buffers {
|
||||||
#[doc(alias = "GST_BUFFER_OFFSET_NONE")]
|
#[doc(alias = "GST_BUFFER_OFFSET_NONE")]
|
||||||
pub const OFFSET_NONE: u64 = ffi::GST_BUFFER_OFFSET_NONE;
|
pub const OFFSET_NONE: u64 = ffi::GST_BUFFER_OFFSET_NONE;
|
||||||
|
@ -35,8 +35,17 @@ option_glib_newtype_from_to!(Buffers, Buffers::OFFSET_NONE);
|
||||||
glib_newtype_display!(Buffers, DisplayableOptionBuffers, Format::Buffers);
|
glib_newtype_display!(Buffers, DisplayableOptionBuffers, Format::Buffers);
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
|
||||||
pub struct Bytes(pub u64);
|
pub struct Bytes(u64);
|
||||||
impl Bytes {
|
impl Bytes {
|
||||||
|
// rustdoc-stripper-ignore-next
|
||||||
|
/// 1K Bytes (1024).
|
||||||
|
pub const K: Self = Self(1024);
|
||||||
|
// rustdoc-stripper-ignore-next
|
||||||
|
/// 1M Bytes (1024 * 1024).
|
||||||
|
pub const M: Self = Self(1024 * 1024);
|
||||||
|
// rustdoc-stripper-ignore-next
|
||||||
|
/// 1G Bytes (1024 * 1024 * 1024).
|
||||||
|
pub const G: Self = Self(1024 * 1024 * 1024);
|
||||||
pub const MAX: Self = Self(u64::MAX - 1);
|
pub const MAX: Self = Self(u64::MAX - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +56,7 @@ option_glib_newtype_from_to!(Bytes, u64::MAX);
|
||||||
glib_newtype_display!(Bytes, DisplayableOptionBytes, Format::Bytes);
|
glib_newtype_display!(Bytes, DisplayableOptionBytes, Format::Bytes);
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
|
||||||
pub struct Default(pub u64);
|
pub struct Default(u64);
|
||||||
impl Default {
|
impl Default {
|
||||||
pub const MAX: Self = Self(u64::MAX - 1);
|
pub const MAX: Self = Self(u64::MAX - 1);
|
||||||
}
|
}
|
||||||
|
@ -61,15 +70,19 @@ glib_newtype_display!(Default, DisplayableOptionDefault, Format::Default);
|
||||||
pub type Time = super::ClockTime;
|
pub type Time = super::ClockTime;
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
|
||||||
pub struct Percent(pub u32);
|
pub struct Percent(u32);
|
||||||
impl Percent {
|
impl Percent {
|
||||||
#[doc(alias = "GST_FORMAT_PERCENT_MAX")]
|
#[doc(alias = "GST_FORMAT_PERCENT_MAX")]
|
||||||
pub const MAX: Self = Self(ffi::GST_FORMAT_PERCENT_MAX as u32);
|
pub const MAX: Self = Self(ffi::GST_FORMAT_PERCENT_MAX as u32);
|
||||||
#[doc(alias = "GST_FORMAT_PERCENT_SCALE")]
|
#[doc(alias = "GST_FORMAT_PERCENT_SCALE")]
|
||||||
pub const SCALE: u32 = ffi::GST_FORMAT_PERCENT_SCALE as u32;
|
pub const SCALE: Self = Self(ffi::GST_FORMAT_PERCENT_SCALE as u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_common_ops_for_newtype_uint!(Percent, u32);
|
impl_common_ops_for_newtype_uint!(
|
||||||
|
Percent,
|
||||||
|
u32,
|
||||||
|
one: ffi::GST_FORMAT_PERCENT_SCALE as u32 / 100,
|
||||||
|
);
|
||||||
impl_signed_div_mul!(Percent, u32);
|
impl_signed_div_mul!(Percent, u32);
|
||||||
|
|
||||||
impl FormattedValue for Option<Percent> {
|
impl FormattedValue for Option<Percent> {
|
||||||
|
@ -227,8 +240,7 @@ impl TryFrom<f32> for Percent {
|
||||||
|
|
||||||
impl std::fmt::Display for Percent {
|
impl std::fmt::Display for Percent {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
const ONE_PERCENT: f32 = Percent::SCALE as f32 / 100.0;
|
std::fmt::Display::fmt(&(self.0 as f32 / (*Percent::ONE) as f32), f)?;
|
||||||
std::fmt::Display::fmt(&(self.0 as f32 / ONE_PERCENT), f)?;
|
|
||||||
f.write_str(" %")
|
f.write_str(" %")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,10 @@ use crate::Format;
|
||||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
|
||||||
pub struct Undefined(pub i64);
|
pub struct Undefined(pub i64);
|
||||||
|
|
||||||
|
impl Undefined {
|
||||||
|
pub const ONE: Undefined = Undefined(1);
|
||||||
|
}
|
||||||
|
|
||||||
impl FormattedValue for Undefined {
|
impl FormattedValue for Undefined {
|
||||||
type FullRange = Undefined;
|
type FullRange = Undefined;
|
||||||
|
|
||||||
|
|
|
@ -173,7 +173,7 @@ USAGE: Choose one of the following options, then press enter:
|
||||||
Command::NextFrame => {
|
Command::NextFrame => {
|
||||||
if let Some(video_sink) = pipeline.property::<Option<Element>>("video-sink") {
|
if let Some(video_sink) = pipeline.property::<Option<Element>>("video-sink") {
|
||||||
// Send the event
|
// Send the event
|
||||||
let step = Step::new(gst::format::Buffers(1), rate.abs(), true, false);
|
let step = Step::new(gst::format::Buffers::ONE, rate.abs(), true, false);
|
||||||
video_sink.send_event(step);
|
video_sink.send_event(step);
|
||||||
println!("Stepping one frame\r");
|
println!("Stepping one frame\r");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue