Skip to content

Commit

Permalink
Implement Display for Duration
Browse files Browse the repository at this point in the history
  • Loading branch information
jhpratt committed Mar 15, 2022
1 parent dbec276 commit 0a3cf3c
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 0 deletions.
38 changes: 38 additions & 0 deletions src/duration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,44 @@ impl Duration {
}

// region: trait impls
/// The format returned by this implementation is not stable and must not be relied upon.
///
/// For the purposes of this implementation, a day is exactly 24 hours and a minute is exactly 60
/// seconds.
impl fmt::Display for Duration {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
/// Format a single item.
macro_rules! item {
($name:literal, $value:expr) => {
match $value {
0 => Ok(()),
value => value.fmt(f).and(f.write_str($name)),
}
};
}

if self.is_zero() {
return f.write_str("0s");
}

let seconds = self.seconds.unsigned_abs();
let nanoseconds = self.nanoseconds.unsigned_abs();

if self.is_negative() {
f.write_str("-")?;
}

item!("d", seconds / 86_400)?;
item!("h", seconds / 3_600 % 24)?;
item!("m", seconds / 60 % 60)?;
item!("s", seconds % 60)?;
item!("ms", nanoseconds / 1_000_000)?;
item!("µs", nanoseconds / 1_000 % 1_000)?;
item!("ns", nanoseconds % 1_000)?;
Ok(())
}
}

impl TryFrom<StdDuration> for Duration {
type Error = error::ConversionRange;

Expand Down
32 changes: 32 additions & 0 deletions tests/integration/duration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,38 @@ fn time_fn() {
assert_eq!(value, 0);
}

#[test]
fn display() {
assert_eq!(0.seconds().to_string(), "0s");
assert_eq!(60.days().to_string(), "60d");
assert_eq!((-48).hours().to_string(), "-2d");
assert_eq!(48.hours().to_string(), "2d");
assert_eq!(1.minutes().to_string(), "1m");
assert_eq!(10.minutes().to_string(), "10m");
assert_eq!(1.seconds().to_string(), "1s");
assert_eq!(10.seconds().to_string(), "10s");
assert_eq!(1.milliseconds().to_string(), "1ms");
assert_eq!(10.milliseconds().to_string(), "10ms");
assert_eq!(100.milliseconds().to_string(), "100ms");
assert_eq!(1.microseconds().to_string(), "1µs");
assert_eq!(10.microseconds().to_string(), "10µs");
assert_eq!(100.microseconds().to_string(), "100µs");
assert_eq!(1.nanoseconds().to_string(), "1ns");
assert_eq!(10.nanoseconds().to_string(), "10ns");
assert_eq!(100.nanoseconds().to_string(), "100ns");

assert_eq!(1.days().to_string(), "1d");
assert_eq!(26.hours().to_string(), "1d2h");
assert_eq!(1_563.minutes().to_string(), "1d2h3m");
assert_eq!(93_784.seconds().to_string(), "1d2h3m4s");
assert_eq!(93_784_005.milliseconds().to_string(), "1d2h3m4s5ms");
assert_eq!(93_784_005_006.microseconds().to_string(), "1d2h3m4s5ms6µs");
assert_eq!(
93_784_005_006_007.nanoseconds().to_string(),
"1d2h3m4s5ms6µs7ns"
);
}

#[test]
fn try_from_std_duration() {
assert_eq!(Duration::try_from(0.std_seconds()), Ok(0.seconds()));
Expand Down

0 comments on commit 0a3cf3c

Please sign in to comment.