mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git
synced 2024-11-25 19:11:06 +00:00
gst/format: new panicking constructors and some Percent fixes
Previous proposition for constructing specific formatted values was to use an operation such as `42 * Default::ONE` which, in retrospect, doesn't seem idiomatic. This commit adds `from_u64` and `from_usize` constructors for most formatted values. Having `from_usize` is convenient when dealing with quantities related to containers indices or length. This also fixes the `Percent` from float constructors from which was derived the `ONE` constant as well as previous display implementation. Also removed the `pub` specifier for `Undefined` inner value. It wasn't removed in a previous commit as `Undefined` can use the full range of the inner type. But now, it seems preferable not to expose the inner value for proper encapsulation and so as to reduce the differences with other formatted values (kind of least astonishment principle).
This commit is contained in:
parent
08551bb1bc
commit
dcf6d16496
7 changed files with 202 additions and 59 deletions
|
@ -294,8 +294,8 @@ 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 start = gst::format::Default::from_u64(1);
|
||||||
let stop = 2 * gst::format::Default::ONE;
|
let stop = gst::format::Default::from_u64(2);
|
||||||
|
|
||||||
{
|
{
|
||||||
let cmeta = AudioClippingMeta::add(buffer.get_mut().unwrap(), start, stop);
|
let cmeta = AudioClippingMeta::add(buffer.get_mut().unwrap(), start, stop);
|
||||||
|
|
|
@ -45,14 +45,15 @@ impl_serde!(Percent, u32);
|
||||||
|
|
||||||
impl Serialize for Undefined {
|
impl Serialize for Undefined {
|
||||||
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 Undefined {
|
impl<'de> Deserialize<'de> for Undefined {
|
||||||
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!();
|
||||||
i64::deserialize(deserializer).map(Undefined)
|
i64::deserialize(deserializer).map(Into::into)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,17 +66,15 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_serialize() {
|
fn test_serialize() {
|
||||||
crate::init().unwrap();
|
|
||||||
|
|
||||||
let pretty_config = ron::ser::PrettyConfig::new().new_line("".to_string());
|
let pretty_config = ron::ser::PrettyConfig::new().new_line("".to_string());
|
||||||
|
|
||||||
let value = GenericFormattedValue::from(Undefined(42));
|
let value = GenericFormattedValue::from(Undefined::from(42));
|
||||||
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("Undefined(42)".to_owned()), res);
|
assert_eq!(Ok("Undefined(42)".to_owned()), res);
|
||||||
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(42 * Default::ONE);
|
let value = GenericFormattedValue::from(Default::from_u64(42));
|
||||||
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 +86,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(42 * Bytes::ONE);
|
let value = GenericFormattedValue::from(Bytes::from_usize(42));
|
||||||
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,25 +98,25 @@ 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(42 * Buffers::ONE);
|
let value = GenericFormattedValue::from(Buffers::from_u64(42));
|
||||||
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 percent = Percent::try_from(0.42).unwrap();
|
let percent = Percent::from_ratio(0.42);
|
||||||
let value = GenericFormattedValue::from(percent);
|
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(420000))".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\":420000}".to_owned(), res);
|
||||||
|
|
||||||
let other = Other::try_from(42).ok();
|
let other = Other::try_from(42).ok();
|
||||||
let value = GenericFormattedValue::Other(Format::Percent, other);
|
let value = GenericFormattedValue::Other(Format::Default, 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(Default, Some(42))".to_owned()), res);
|
||||||
let res = serde_json::to_string(&value).unwrap();
|
let res = serde_json::to_string(&value).unwrap();
|
||||||
assert_eq!("{\"Other\":[\"Percent\",42]}".to_owned(), res);
|
assert_eq!("{\"Other\":[\"Default\",42]}".to_owned(), res);
|
||||||
|
|
||||||
let value = GenericFormattedValue::new(Format::__Unknown(7), 42);
|
let value = GenericFormattedValue::new(Format::__Unknown(7), 42);
|
||||||
let res = ron::ser::to_string_pretty(&value, pretty_config);
|
let res = ron::ser::to_string_pretty(&value, pretty_config);
|
||||||
|
@ -128,31 +127,27 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_deserialize() {
|
fn test_deserialize() {
|
||||||
crate::init().unwrap();
|
|
||||||
|
|
||||||
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(42 * Default::ONE));
|
assert_eq!(value_de, GenericFormattedValue::from(Default::from_u64(42)));
|
||||||
|
|
||||||
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(42 * Default::ONE));
|
assert_eq!(value_de, GenericFormattedValue::from(Default::from_u64(42)));
|
||||||
|
|
||||||
let value_ron = "Other(Percent, Some(42))";
|
let value_ron = "Other(Buffers, Some(42))";
|
||||||
let gfv_value = GenericFormattedValue::Other(Format::Percent, Some(42 * Other::ONE));
|
let gfv_value = GenericFormattedValue::Other(Format::Buffers, 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);
|
||||||
|
|
||||||
let value_json = "{\"Other\":[\"Percent\",42]}";
|
let value_json = "{\"Other\":[\"Buffers\",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, gfv_value);
|
assert_eq!(value_de, gfv_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_serde_roundtrip() {
|
fn test_serde_roundtrip() {
|
||||||
crate::init().unwrap();
|
|
||||||
|
|
||||||
macro_rules! test_roundrip(
|
macro_rules! test_roundrip(
|
||||||
($value:expr) => {
|
($value:expr) => {
|
||||||
let value_ser = ron::ser::to_string(&$value).unwrap();
|
let value_ser = ron::ser::to_string(&$value).unwrap();
|
||||||
|
@ -161,15 +156,15 @@ mod tests {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
test_roundrip!(GenericFormattedValue::Undefined(Undefined(42)));
|
test_roundrip!(GenericFormattedValue::Undefined(Undefined::from(42)));
|
||||||
test_roundrip!(GenericFormattedValue::from(42 * Default::ONE));
|
test_roundrip!(GenericFormattedValue::from(Default::from_u64(42)));
|
||||||
test_roundrip!(GenericFormattedValue::from(42 * Bytes::ONE));
|
test_roundrip!(GenericFormattedValue::from(Bytes::from_u64(42)));
|
||||||
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(42 * Buffers::ONE));
|
test_roundrip!(GenericFormattedValue::from(Buffers::from_u64(42)));
|
||||||
test_roundrip!(GenericFormattedValue::from(42 * Percent::ONE));
|
test_roundrip!(GenericFormattedValue::from(Percent::from_percent(42)));
|
||||||
let gfv_value = GenericFormattedValue::Other(Format::Percent, Other::try_from(42).ok());
|
let gfv_value = GenericFormattedValue::Other(Format::Default, 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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,32 @@ impl Other {
|
||||||
pub const MAX: Self = Self(u64::MAX - 1);
|
pub const MAX: Self = Self(u64::MAX - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Other {
|
||||||
|
// rustdoc-stripper-ignore-next
|
||||||
|
/// Builds a new `Other` value with the provided quantity.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the provided quantity equals `u64::MAX`,
|
||||||
|
/// which is reserved for `None` in C.
|
||||||
|
#[track_caller]
|
||||||
|
pub fn from_u64(quantity: u64) -> Self {
|
||||||
|
Other::try_from(quantity).expect("`Other` value out of range")
|
||||||
|
}
|
||||||
|
|
||||||
|
// rustdoc-stripper-ignore-next
|
||||||
|
/// Builds a new `Other` value with the provided quantity.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the provided quantity equals `u64::MAX`,
|
||||||
|
/// which is reserved for `None` in C.
|
||||||
|
#[track_caller]
|
||||||
|
pub fn from_usize(quantity: usize) -> Self {
|
||||||
|
Other::from_u64(quantity.try_into().unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl_common_ops_for_newtype_uint!(Other, u64);
|
impl_common_ops_for_newtype_uint!(Other, u64);
|
||||||
impl_signed_div_mul!(Other, u64);
|
impl_signed_div_mul!(Other, u64);
|
||||||
option_glib_newtype_from_to!(Other, u64::MAX);
|
option_glib_newtype_from_to!(Other, u64::MAX);
|
||||||
|
@ -82,7 +108,7 @@ impl GenericFormattedValue {
|
||||||
pub fn new(format: Format, value: i64) -> Self {
|
pub fn new(format: Format, value: i64) -> Self {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
match format {
|
match format {
|
||||||
Format::Undefined => Self::Undefined(Undefined(value)),
|
Format::Undefined => Self::Undefined(value.into()),
|
||||||
Format::Default => Self::Default(unsafe { FromGlib::from_glib(value) }),
|
Format::Default => Self::Default(unsafe { FromGlib::from_glib(value) }),
|
||||||
Format::Bytes => Self::Bytes(unsafe { FromGlib::from_glib(value) }),
|
Format::Bytes => Self::Bytes(unsafe { FromGlib::from_glib(value) }),
|
||||||
Format::Time => Self::Time(unsafe { FromGlib::from_glib(value) }),
|
Format::Time => Self::Time(unsafe { FromGlib::from_glib(value) }),
|
||||||
|
@ -109,7 +135,7 @@ impl GenericFormattedValue {
|
||||||
pub fn value(&self) -> i64 {
|
pub fn value(&self) -> i64 {
|
||||||
unsafe {
|
unsafe {
|
||||||
match *self {
|
match *self {
|
||||||
Self::Undefined(v) => v.0,
|
Self::Undefined(v) => *v,
|
||||||
Self::Default(v) => v.into_raw_value(),
|
Self::Default(v) => v.into_raw_value(),
|
||||||
Self::Bytes(v) => v.into_raw_value(),
|
Self::Bytes(v) => v.into_raw_value(),
|
||||||
Self::Time(v) => v.into_raw_value(),
|
Self::Time(v) => v.into_raw_value(),
|
||||||
|
@ -390,9 +416,9 @@ mod tests {
|
||||||
let other_none: Option<Other> = Other::try_from(u64::MAX).ok();
|
let other_none: Option<Other> = Other::try_from(u64::MAX).ok();
|
||||||
assert!(other_none.is_none());
|
assert!(other_none.is_none());
|
||||||
|
|
||||||
let other_10 = Other::try_from(10).unwrap();
|
let other_10 = Other::from_u64(10);
|
||||||
let other_20 = Other::try_from(20).unwrap();
|
let other_20 = Other::from_usize(20);
|
||||||
let other_30 = Other::try_from(30).unwrap();
|
let other_30 = Other::from_u64(30);
|
||||||
|
|
||||||
assert_eq!(other_10 + other_20, other_30);
|
assert_eq!(other_10 + other_20, other_30);
|
||||||
assert_eq!(other_30 - other_20, other_10);
|
assert_eq!(other_30 - other_20, other_10);
|
||||||
|
@ -409,7 +435,7 @@ mod tests {
|
||||||
GenericFormattedValue::new(Format::__Unknown(128), 42);
|
GenericFormattedValue::new(Format::__Unknown(128), 42);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
gen_other_42,
|
gen_other_42,
|
||||||
GenericFormattedValue::Other(Format::__Unknown(128), Some(Other(42)))
|
GenericFormattedValue::Other(Format::__Unknown(128), Other::try_from(42).ok())
|
||||||
);
|
);
|
||||||
assert_eq!(gen_other_42.format(), Format::__Unknown(128));
|
assert_eq!(gen_other_42.format(), Format::__Unknown(128));
|
||||||
assert_eq!(gen_other_42.value(), 42);
|
assert_eq!(gen_other_42.value(), 42);
|
||||||
|
@ -438,7 +464,7 @@ mod tests {
|
||||||
p_gen_other_42,
|
p_gen_other_42,
|
||||||
GenericSignedFormattedValue::Other(
|
GenericSignedFormattedValue::Other(
|
||||||
Format::__Unknown(128),
|
Format::__Unknown(128),
|
||||||
Some(Signed::Positive(Other(42))),
|
Some(Signed::Positive(Other::from_u64(42))),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -447,7 +473,7 @@ mod tests {
|
||||||
n_gen_other_42,
|
n_gen_other_42,
|
||||||
GenericSignedFormattedValue::Other(
|
GenericSignedFormattedValue::Other(
|
||||||
Format::__Unknown(128),
|
Format::__Unknown(128),
|
||||||
Some(Signed::Negative(Other(42))),
|
Some(Signed::Negative(Other::from_u64(42))),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1605,7 +1605,7 @@ macro_rules! glib_newtype_display {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
($typ:ty, $displayable_option_name:ident, Format::$format:ident$(,)?) => {
|
($typ:ty, $displayable_option_name:ident, Format::$format:ident) => {
|
||||||
glib_newtype_display!($typ, Format::$format);
|
glib_newtype_display!($typ, Format::$format);
|
||||||
|
|
||||||
pub struct $displayable_option_name(Option<$typ>);
|
pub struct $displayable_option_name(Option<$typ>);
|
||||||
|
|
|
@ -73,10 +73,17 @@
|
||||||
//! assert_eq!(Default::try_from(42), Ok(default));
|
//! assert_eq!(Default::try_from(42), Ok(default));
|
||||||
//! assert_eq!(Default::try_from(42).ok(), Some(default));
|
//! assert_eq!(Default::try_from(42).ok(), Some(default));
|
||||||
//!
|
//!
|
||||||
//! // `ClockTime` provides specific constructors:
|
//! // `ClockTime` provides specific constructors,
|
||||||
|
//! // which can panic if the requested value is out of range.
|
||||||
//! let time = ClockTime::from_nseconds(45_834_908_569_837);
|
//! let time = ClockTime::from_nseconds(45_834_908_569_837);
|
||||||
//! let time = ClockTime::from_seconds(20);
|
//! let time = ClockTime::from_seconds(20);
|
||||||
//!
|
//!
|
||||||
|
//! // Other formatted values also come with (panicking) constructors:
|
||||||
|
//! let buffers_nb = Buffers::from_u64(512);
|
||||||
|
//! let received = Bytes::from_u64(64);
|
||||||
|
//! let sample_size = Bytes::from_usize([0u8; 4].len());
|
||||||
|
//! let quantity = Default::from_u64(42);
|
||||||
|
//!
|
||||||
//! // This can be convenient:
|
//! // This can be convenient:
|
||||||
//! assert_eq!(
|
//! assert_eq!(
|
||||||
//! 20 * ClockTime::MSECOND,
|
//! 20 * ClockTime::MSECOND,
|
||||||
|
@ -87,24 +94,32 @@
|
||||||
//! ClockTime::from_nseconds(40_000_000_000),
|
//! ClockTime::from_nseconds(40_000_000_000),
|
||||||
//! );
|
//! );
|
||||||
//!
|
//!
|
||||||
//! // Specific formatted values provide the `ONE` value:
|
//! // `ZERO` and `NONE` can come in handy sometimes:
|
||||||
//! assert_eq!(*(128 * Buffers::ONE), 128);
|
|
||||||
//!
|
|
||||||
//! // `ZERO` and `NONE` can also come in handy sometimes:
|
|
||||||
//! assert_eq!(*Buffers::ZERO, 0);
|
//! assert_eq!(*Buffers::ZERO, 0);
|
||||||
//! assert!(ClockTime::NONE.is_none());
|
//! assert!(ClockTime::NONE.is_none());
|
||||||
//!
|
//!
|
||||||
|
//! // Specific formatted values provide the `ONE` value:
|
||||||
|
//! assert_eq!(*(128 * Buffers::ONE), 128);
|
||||||
|
//!
|
||||||
//! // `Bytes` also comes with usual multipliers:
|
//! // `Bytes` also comes with usual multipliers:
|
||||||
//! assert_eq!(*(512 * Bytes::K), 512 * 1024);
|
//! assert_eq!(*(512 * Bytes::K), 512 * 1024);
|
||||||
//! assert_eq!(*(8 * Bytes::M), 8 * 1024 * 1024);
|
//! assert_eq!(*(8 * Bytes::M), 8 * 1024 * 1024);
|
||||||
//! assert_eq!(*(4 * Bytes::G), 4 * 1024 * 1024 * 1024);
|
//! assert_eq!(*(4 * Bytes::G), 4 * 1024 * 1024 * 1024);
|
||||||
//!
|
//!
|
||||||
//! // `Percent` can be built from a float:
|
//! // `Percent` can be built from a floating point ratio:
|
||||||
//! let a_quarter = Percent::try_from(0.25).unwrap();
|
//! let a_quarter_from_ratio = Percent::from_ratio(0.25);
|
||||||
//! // `Percent` has `SCALE` which represents 100%:
|
//! // ... from a percent integer value:
|
||||||
//! assert_eq!(Percent::SCALE / 4, a_quarter);
|
//! let a_quarter = Percent::from_percent(25);
|
||||||
//! // ... and `ONE` which is 1%:
|
//! assert_eq!(a_quarter, a_quarter_from_ratio);
|
||||||
|
//! // ... from a part per million integer value:
|
||||||
|
//! let a_quarter_from_ppm = Percent::from_ppm(25 * 10_000);
|
||||||
|
//! assert_eq!(a_quarter, a_quarter_from_ppm);
|
||||||
|
//! // ... `MAX` which represents 100%:
|
||||||
|
//! assert_eq!(Percent::MAX / 4, a_quarter);
|
||||||
|
//! // ... `ONE` which is 1%:
|
||||||
//! assert_eq!(25 * Percent::ONE, a_quarter);
|
//! assert_eq!(25 * Percent::ONE, a_quarter);
|
||||||
|
//! // ... and `SCALE` which is 1% in ppm:
|
||||||
|
//! assert_eq!(Percent::SCALE, Percent::from_ppm(10_000));
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! ### Displaying a formatted value
|
//! ### Displaying a formatted value
|
||||||
|
|
|
@ -28,6 +28,32 @@ impl Buffers {
|
||||||
pub const MAX: Self = Self(Self::OFFSET_NONE - 1);
|
pub const MAX: Self = Self(Self::OFFSET_NONE - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Buffers {
|
||||||
|
// rustdoc-stripper-ignore-next
|
||||||
|
/// Builds a new `Buffers` formatted value with the provided buffers count.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the provided count equals `u64::MAX`,
|
||||||
|
/// which is reserved for `None` in C.
|
||||||
|
#[track_caller]
|
||||||
|
pub fn from_u64(buffers: u64) -> Self {
|
||||||
|
Buffers::try_from(buffers).expect("`Buffers` value out of range")
|
||||||
|
}
|
||||||
|
|
||||||
|
// rustdoc-stripper-ignore-next
|
||||||
|
/// Builds a new `Buffers` formatted value with the provided buffers count.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the provided count equals `u64::MAX`,
|
||||||
|
/// which is reserved for `None` in C.
|
||||||
|
#[track_caller]
|
||||||
|
pub fn from_usize(buffers: usize) -> Self {
|
||||||
|
Buffers::from_u64(buffers.try_into().unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl_common_ops_for_newtype_uint!(Buffers, u64);
|
impl_common_ops_for_newtype_uint!(Buffers, u64);
|
||||||
impl_signed_div_mul!(Buffers, u64);
|
impl_signed_div_mul!(Buffers, u64);
|
||||||
impl_format_value_traits!(Buffers, Buffers, Buffers, u64);
|
impl_format_value_traits!(Buffers, Buffers, Buffers, u64);
|
||||||
|
@ -49,6 +75,32 @@ impl Bytes {
|
||||||
pub const MAX: Self = Self(u64::MAX - 1);
|
pub const MAX: Self = Self(u64::MAX - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Bytes {
|
||||||
|
// rustdoc-stripper-ignore-next
|
||||||
|
/// Builds a new `Bytes` formatted value with the provided bytes count.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the provided count equals `u64::MAX`,
|
||||||
|
/// which is reserved for `None` in C.
|
||||||
|
#[track_caller]
|
||||||
|
pub fn from_u64(bytes: u64) -> Self {
|
||||||
|
Bytes::try_from(bytes).expect("`Bytes` value out of range")
|
||||||
|
}
|
||||||
|
|
||||||
|
// rustdoc-stripper-ignore-next
|
||||||
|
/// Builds a new `Bytes` formatted value with the provided bytes count.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the provided count equals `u64::MAX`,
|
||||||
|
/// which is reserved for `None` in C.
|
||||||
|
#[track_caller]
|
||||||
|
pub fn from_usize(bytes: usize) -> Self {
|
||||||
|
Bytes::from_u64(bytes.try_into().unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl_common_ops_for_newtype_uint!(Bytes, u64);
|
impl_common_ops_for_newtype_uint!(Bytes, u64);
|
||||||
impl_signed_div_mul!(Bytes, u64);
|
impl_signed_div_mul!(Bytes, u64);
|
||||||
impl_format_value_traits!(Bytes, Bytes, Bytes, u64);
|
impl_format_value_traits!(Bytes, Bytes, Bytes, u64);
|
||||||
|
@ -61,6 +113,32 @@ impl Default {
|
||||||
pub const MAX: Self = Self(u64::MAX - 1);
|
pub const MAX: Self = Self(u64::MAX - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default {
|
||||||
|
// rustdoc-stripper-ignore-next
|
||||||
|
/// Builds a new `Default` formatted value with the provided quantity.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the provided quantity equals `u64::MAX`,
|
||||||
|
/// which is reserved for `None` in C.
|
||||||
|
#[track_caller]
|
||||||
|
pub fn from_u64(quantity: u64) -> Self {
|
||||||
|
Default::try_from(quantity).expect("`Default` value out of range")
|
||||||
|
}
|
||||||
|
|
||||||
|
// rustdoc-stripper-ignore-next
|
||||||
|
/// Builds a new `Default` formatted value with the provided quantity.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the provided quantity equals `u64::MAX`,
|
||||||
|
/// which is reserved for `None` in C.
|
||||||
|
#[track_caller]
|
||||||
|
pub fn from_usize(quantity: usize) -> Self {
|
||||||
|
Default::from_u64(quantity.try_into().unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl_common_ops_for_newtype_uint!(Default, u64);
|
impl_common_ops_for_newtype_uint!(Default, u64);
|
||||||
impl_signed_div_mul!(Default, u64);
|
impl_signed_div_mul!(Default, u64);
|
||||||
impl_format_value_traits!(Default, Default, Default, u64);
|
impl_format_value_traits!(Default, Default, Default, u64);
|
||||||
|
@ -76,13 +154,42 @@ impl Percent {
|
||||||
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: Self = Self(ffi::GST_FORMAT_PERCENT_SCALE as u32);
|
pub const SCALE: Self = Self(ffi::GST_FORMAT_PERCENT_SCALE as u32);
|
||||||
|
|
||||||
|
// rustdoc-stripper-ignore-next
|
||||||
|
/// Builds a new `Percent` with the provided percent value.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the provided value is larger than 100.
|
||||||
|
#[track_caller]
|
||||||
|
pub fn from_percent(percent: u32) -> Self {
|
||||||
|
Percent::try_from(*Self::SCALE * percent).expect("`Percent` value out of range")
|
||||||
|
}
|
||||||
|
|
||||||
|
// rustdoc-stripper-ignore-next
|
||||||
|
/// Builds a new `Percent` with the provided parts per million value.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the provided value is larger than [`Self::MAX`].
|
||||||
|
#[track_caller]
|
||||||
|
pub fn from_ppm(ppm: u32) -> Self {
|
||||||
|
Percent::try_from(ppm).expect("`Percent` value out of range")
|
||||||
|
}
|
||||||
|
|
||||||
|
// rustdoc-stripper-ignore-next
|
||||||
|
/// Builds a new `Percent` with the provided ratio.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the provided radio is out of the range [0.0, 1.0].
|
||||||
|
#[track_caller]
|
||||||
|
pub fn from_ratio(ratio: f32) -> Self {
|
||||||
|
Percent::try_from(ratio).expect("`Percent` ratio out of range")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_common_ops_for_newtype_uint!(
|
impl_common_ops_for_newtype_uint!(Percent, u32, one: ffi::GST_FORMAT_PERCENT_SCALE as u32);
|
||||||
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> {
|
||||||
|
@ -217,7 +324,7 @@ impl TryFrom<f64> for Percent {
|
||||||
Err(TryPercentFromFloatError(()))
|
Err(TryPercentFromFloatError(()))
|
||||||
} else {
|
} else {
|
||||||
Ok(Percent(
|
Ok(Percent(
|
||||||
(v * ffi::GST_FORMAT_PERCENT_SCALE as f64).round() as u32
|
(v * ffi::GST_FORMAT_PERCENT_MAX as f64).round() as u32
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,7 +339,7 @@ impl TryFrom<f32> for Percent {
|
||||||
Err(TryPercentFromFloatError(()))
|
Err(TryPercentFromFloatError(()))
|
||||||
} else {
|
} else {
|
||||||
Ok(Percent(
|
Ok(Percent(
|
||||||
(v * ffi::GST_FORMAT_PERCENT_SCALE as f32).round() as u32
|
(v * ffi::GST_FORMAT_PERCENT_MAX as f32).round() as u32
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -240,7 +347,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 {
|
||||||
std::fmt::Display::fmt(&(self.0 as f32 / (*Percent::ONE) as f32), f)?;
|
std::fmt::Display::fmt(&(self.0 as f32 / (*Percent::SCALE) as f32), f)?;
|
||||||
f.write_str(" %")
|
f.write_str(" %")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use super::{FormattedValueError, GenericFormattedValue, Signed};
|
||||||
use crate::Format;
|
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(i64);
|
||||||
|
|
||||||
impl Undefined {
|
impl Undefined {
|
||||||
pub const ONE: Undefined = Undefined(1);
|
pub const ONE: Undefined = Undefined(1);
|
||||||
|
|
Loading…
Reference in a new issue