use core::str::FromStr;
use alloc::string::String;
use crate::parsers;
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
pub enum Duration {
YMDHMS {
year: u32,
month: u32,
day: u32,
hour: u32,
minute: u32,
second: u32,
millisecond: u32,
},
Weeks(u32),
}
impl Duration {
pub fn is_zero(&self) -> bool {
*self
== Duration::YMDHMS {
year: 0,
month: 0,
day: 0,
hour: 0,
minute: 0,
second: 0,
millisecond: 0,
}
|| *self == Duration::Weeks(0)
}
}
impl Default for Duration {
fn default() -> Duration {
Duration::YMDHMS {
year: 0,
month: 0,
day: 0,
hour: 0,
minute: 0,
second: 0,
millisecond: 0,
}
}
}
impl FromStr for Duration {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
duration(s)
}
}
impl From<Duration> for ::core::time::Duration {
fn from(duration: Duration) -> Self {
match duration {
Duration::YMDHMS {
year,
month,
day,
hour,
minute,
second,
millisecond,
} => {
let secs = u64::from(year) * 365 * 86_400
+ u64::from(month) * 30 * 86_400
+ u64::from(day) * 86_400
+ u64::from(hour) * 3600
+ u64::from(minute) * 60
+ u64::from(second);
let nanos = millisecond * 1_000_000;
Self::new(secs, nanos)
}
Duration::Weeks(week) => {
let secs = u64::from(week) * 7 * 86_400;
Self::from_secs(secs)
}
}
}
}
pub fn duration(string: &str) -> Result<Duration, String> {
if let Ok((_left_overs, parsed)) = parsers::parse_duration(string.as_bytes()) {
Ok(parsed)
} else {
Err(format!("Failed to parse duration: {}", string))
}
}