use std::fmt;
use std::ops::{Add, Sub};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct Duration(i64);
impl Duration {
#[inline(always)]
pub fn from_millis(milliseconds: i64) -> Self {
Self(milliseconds)
}
#[inline(always)]
pub fn from_secs(seconds: i64) -> Self {
Self(seconds * 1_000)
}
#[inline(always)]
pub fn from_mins(minutes: i64) -> Self {
Self(minutes * 60_000)
}
#[inline(always)]
pub fn from_hours(hours: i64) -> Self {
Self(hours * 3_600_000)
}
#[inline(always)]
pub fn from_days(days: i64) -> Self {
Self(days * 86_400_000)
}
#[inline(always)]
pub fn as_millis(self) -> i64 {
self.0
}
}
impl Add for Duration {
type Output = Self;
#[inline(always)]
fn add(self, rhs: Self) -> Self::Output {
Self(self.0 + rhs.0)
}
}
impl Sub for Duration {
type Output = Self;
#[inline(always)]
fn sub(self, rhs: Self) -> Self::Output {
Self(self.0 - rhs.0)
}
}
impl fmt::Display for Duration {
#[inline(always)]
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut milliseconds = self.0.unsigned_abs();
let days = milliseconds / 86_400_000;
milliseconds %= 86_400_000;
let hours = milliseconds / 3_600_000;
milliseconds %= 3_600_000;
let minutes = milliseconds / 60_000;
milliseconds %= 60_000;
let seconds = milliseconds / 1_000;
milliseconds %= 1_000;
if self.0 < 0 {
formatter.write_str("-")?;
}
let mut needs_space = false;
write_part(formatter, &mut needs_space, days, "d")?;
write_part(formatter, &mut needs_space, hours, "h")?;
write_part(formatter, &mut needs_space, minutes, "m")?;
write_part(formatter, &mut needs_space, seconds, "s")?;
write_part(formatter, &mut needs_space, milliseconds, "ms")?;
if !needs_space {
formatter.write_str("0ms")?;
}
Ok(())
}
}
#[inline(always)]
fn write_part(
formatter: &mut fmt::Formatter<'_>,
needs_space: &mut bool,
value: u64,
suffix: &str,
) -> fmt::Result {
if value == 0 {
return Ok(());
}
if *needs_space {
formatter.write_str(" ")?;
}
write!(formatter, "{value}{suffix}")?;
*needs_space = true;
Ok(())
}