use core::str::FromStr;
use derive_more::{Debug, Display};
#[cfg(feature = "zerocopy")]
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::{ParseTimedeltaError, Timedelta};
#[repr(transparent)]
#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
#[display("{}", Timedelta(*_0))]
#[debug("{self}")]
#[cfg_attr(feature = "zerocopy", derive(FromBytes, IntoBytes, Immutable, KnownLayout))]
pub struct Uptime(pub(crate) i64);
#[repr(transparent)]
#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
#[display("{}", Timedelta(*_0))]
#[debug("{self}")]
#[cfg_attr(feature = "zerocopy", derive(FromBytes, IntoBytes, Immutable, KnownLayout))]
pub struct RawUptime(pub(crate) i64);
#[repr(transparent)]
#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
#[display("{}", Timedelta(*_0))]
#[debug("{self}")]
#[cfg_attr(feature = "zerocopy", derive(FromBytes, IntoBytes, Immutable, KnownLayout))]
pub struct BootUptime(pub(crate) i64);
macro_rules! read_as_span {
($point:ident) => {
impl FromStr for $point {
type Err = ParseTimedeltaError;
fn from_str(text: &str) -> Result<Self, Self::Err> {
text.parse().map(|span: Timedelta| Self(span.0))
}
}
};
}
read_as_span!(Uptime);
read_as_span!(RawUptime);
read_as_span!(BootUptime);
#[cfg(test)]
mod tests {
use alloc::format;
use alloc::string::ToString as _;
use crate::{BootUptime, ParseTimedeltaError, RawUptime, Uptime};
#[test]
fn a_point_from_boot_reads_back_from_its_span() {
let uptime = Uptime::from_millis(90_250);
assert_eq!(uptime.to_string(), "1m30s250ms", "written as the span since the origin");
assert_eq!("1m30s250ms".parse(), Ok(uptime), "and read back");
assert_eq!("2h".parse(), Ok(BootUptime::from_secs(7_200)), "on every clock from boot");
assert_eq!("-".parse::<RawUptime>(), Err(ParseTimedeltaError), "refused as a span is");
}
#[test]
fn a_width_pads_a_point_from_boot_as_it_pads_a_span() {
assert_eq!(format!("[{:>8}]", Uptime::from_millis(500)), "[ 500ms]", "padded");
assert_eq!(format!("{:?}", RawUptime::from_secs(2)), "2s", "and debugged as written");
}
}