gst/format: fix Percent Display impl

- The `GST_FORMAT_PERCENT_SCALE` was not used to compute the value
  to display.
- Added `Display` examples in the format module documentation.
- Simplified `glib_newtype_display` macro.
This commit is contained in:
François Laignel 2022-10-09 23:47:51 +02:00
parent 8e2c621a9f
commit f6336b1be3
5 changed files with 60 additions and 45 deletions

View file

@ -22,7 +22,7 @@ impl Other {
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);
glib_newtype_display!(Other, DisplayableOther, DisplayableOptionOther); glib_newtype_display!(Other, DisplayableOptionOther);
impl TryFrom<u64> for Other { impl TryFrom<u64> for Other {
type Error = GlibNoneError; type Error = GlibNoneError;

View file

@ -1531,13 +1531,11 @@ macro_rules! option_glib_newtype_from_to {
}; };
} }
// FIXME we could automatically build `$displayable_name` and // FIXME we could automatically build `$displayable_option_name`
// `$displayable_option_name` if `concat_idents!` was stable. // if `concat_idents!` was stable.
// See: https://doc.rust-lang.org/std/macro.concat_idents.html // See: https://doc.rust-lang.org/std/macro.concat_idents.html
macro_rules! glib_newtype_display { macro_rules! glib_newtype_display {
($typ:ty, $displayable_name:ident) => { ($typ:ty) => {
pub struct $displayable_name($typ);
impl std::fmt::Display for $typ { impl std::fmt::Display for $typ {
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, f) std::fmt::Display::fmt(&self.0, f)
@ -1545,16 +1543,14 @@ macro_rules! glib_newtype_display {
} }
impl crate::utils::Displayable for $typ { impl crate::utils::Displayable for $typ {
type DisplayImpl = $typ; type DisplayImpl = Self;
fn display(self) -> $typ { fn display(self) -> Self {
self self
} }
} }
}; };
($typ:ty, $displayable_name:ident, Format::$format:ident$(,)?) => { ($typ:ty, Format::$format:ident) => {
pub struct $displayable_name($typ);
impl std::fmt::Display for $typ { impl std::fmt::Display for $typ {
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, f)?; std::fmt::Display::fmt(&self.0, f)?;
@ -1564,15 +1560,15 @@ macro_rules! glib_newtype_display {
} }
impl crate::utils::Displayable for $typ { impl crate::utils::Displayable for $typ {
type DisplayImpl = $typ; type DisplayImpl = Self;
fn display(self) -> $typ { fn display(self) -> Self {
self self
} }
} }
}; };
($typ:ty, $displayable_name:ident, $displayable_option_name:ident) => { ($typ:ty, $displayable_option_name:ident) => {
glib_newtype_display!($typ, $displayable_name); glib_newtype_display!($typ);
pub struct $displayable_option_name(Option<$typ>); pub struct $displayable_option_name(Option<$typ>);
@ -1594,8 +1590,8 @@ macro_rules! glib_newtype_display {
} }
}; };
($typ:ty, $displayable_name:ident, $displayable_option_name:ident, Format::$format:ident$(,)?) => { ($typ:ty, $displayable_option_name:ident, Format::$format:ident$(,)?) => {
glib_newtype_display!($typ, $displayable_name, Format::$format); glib_newtype_display!($typ, Format::$format);
pub struct $displayable_option_name(Option<$typ>); pub struct $displayable_option_name(Option<$typ>);
@ -1604,8 +1600,7 @@ macro_rules! glib_newtype_display {
if let Some(val) = self.0.as_ref() { if let Some(val) = self.0.as_ref() {
std::fmt::Display::fmt(val, f) std::fmt::Display::fmt(val, f)
} else { } else {
f.write_str("undef. ")?; write!(f, "undef. {}", Format::$format)
std::fmt::Display::fmt(&Format::$format, f)
} }
} }
} }

View file

@ -72,6 +72,10 @@
//! //!
//! assert_eq!(format!("{}", time), "12:43:54.908569837"); //! assert_eq!(format!("{}", time), "12:43:54.908569837");
//! assert_eq!(format!("{:.0}", time), "12:43:54"); //! assert_eq!(format!("{:.0}", time), "12:43:54");
//!
//! let percent = gst::format::Percent::try_from(0.1234).unwrap();
//! assert_eq!(format!("{}", percent), "12.34 %");
//! assert_eq!(format!("{:5.1}", percent), " 12.3 %");
//! ``` //! ```
//! //!
//! ## Some operations available on specific formatted values //! ## Some operations available on specific formatted values
@ -858,13 +862,17 @@ mod tests {
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(Some(Percent(42))); let gv_1 = GenericFormattedValue::Percent(Percent::try_from(0.42).ok());
assert_eq!(&format!("{gv_1}"), "42 %"); assert_eq!(&format!("{gv_1}"), "42 %");
assert_eq!( assert_eq!(
&format!("{}", GenericFormattedValue::Percent(None)), &format!("{}", GenericFormattedValue::Percent(None)),
"undef. %" "undef. %"
); );
let percent = Percent::try_from(0.1234).unwrap();
assert_eq!(&format!("{percent}"), "12.34 %");
assert_eq!(&format!("{percent:5.1}"), " 12.3 %");
let other: Other = 42.try_into().unwrap(); let other: Other = 42.try_into().unwrap();
assert_eq!(&format!("{other}"), "42"); assert_eq!(&format!("{other}"), "42");

View file

@ -32,12 +32,7 @@ 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);
option_glib_newtype_from_to!(Buffers, Buffers::OFFSET_NONE); option_glib_newtype_from_to!(Buffers, Buffers::OFFSET_NONE);
glib_newtype_display!( glib_newtype_display!(Buffers, DisplayableOptionBuffers, Format::Buffers);
Buffers,
DisplayableBuffers,
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(pub u64);
@ -49,12 +44,7 @@ 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);
option_glib_newtype_from_to!(Bytes, u64::MAX); option_glib_newtype_from_to!(Bytes, u64::MAX);
glib_newtype_display!( glib_newtype_display!(Bytes, DisplayableOptionBytes, Format::Bytes);
Bytes,
DisplayableBytes,
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(pub u64);
@ -66,12 +56,7 @@ 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);
option_glib_newtype_from_to!(Default, u64::MAX); option_glib_newtype_from_to!(Default, u64::MAX);
glib_newtype_display!( glib_newtype_display!(Default, DisplayableOptionDefault, Format::Default);
Default,
DisplayableDefault,
DisplayableOptionDefault,
Format::Default,
);
pub type Time = super::ClockTime; pub type Time = super::ClockTime;
@ -86,12 +71,6 @@ impl Percent {
impl_common_ops_for_newtype_uint!(Percent, u32); impl_common_ops_for_newtype_uint!(Percent, u32);
impl_signed_div_mul!(Percent, u32); impl_signed_div_mul!(Percent, u32);
glib_newtype_display!(
Percent,
DisplayablePercent,
DisplayableOptionPercent,
Format::Percent,
);
impl FormattedValue for Option<Percent> { impl FormattedValue for Option<Percent> {
type FullRange = Option<Percent>; type FullRange = Option<Percent>;
@ -245,3 +224,36 @@ impl TryFrom<f32> for Percent {
} }
} }
} }
impl std::fmt::Display for Percent {
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 / ONE_PERCENT), f)?;
f.write_str(" %")
}
}
impl crate::utils::Displayable for Percent {
type DisplayImpl = Self;
fn display(self) -> Self {
self
}
}
pub struct DisplayableOptionPercent(Option<Percent>);
impl std::fmt::Display for DisplayableOptionPercent {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
if let Some(val) = self.0.as_ref() {
std::fmt::Display::fmt(val, f)
} else {
f.write_str("undef. %")
}
}
}
impl crate::utils::Displayable for Option<Percent> {
type DisplayImpl = DisplayableOptionPercent;
fn display(self) -> Self::DisplayImpl {
DisplayableOptionPercent(self)
}
}

View file

@ -108,4 +108,4 @@ impl From<Undefined> for Signed<u64> {
} }
} }
glib_newtype_display!(Undefined, DisplayableUndefined, Format::Undefined); glib_newtype_display!(Undefined, Format::Undefined);