diff --git a/fitnesstrax/app/src/types.rs b/fitnesstrax/app/src/types.rs index f017596..09a7c71 100644 --- a/fitnesstrax/app/src/types.rs +++ b/fitnesstrax/app/src/types.rs @@ -56,6 +56,66 @@ pub enum FormatOption { Full, } +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct Time(chrono::NaiveTime); + +impl Time { + fn format(&self, option: FormatOption) -> String { + match option { + FormatOption::Abbreviated => self.0.format("%H:%M"), + FormatOption::Full => self.0.format("%H:%M:%S"), + } + .to_string() + } + + fn parse(s: &str) -> Result { + let parts = s + .split(':') + .map(|part| part.parse::().map_err(|_| ParseError)) + .collect::, ParseError>>()?; + match parts.len() { + 0 => Err(ParseError), + 1 => Err(ParseError), + 2 => Ok(Time( + chrono::NaiveTime::from_hms_opt(parts[0], parts[1], 0).unwrap(), + )), + 3 => Ok(Time( + chrono::NaiveTime::from_hms_opt(parts[0], parts[1], parts[2]).unwrap(), + )), + _ => Err(ParseError), + } + } +} + +/* +impl std::ops::Add for Time { + type Output = Time; + fn add(self, rside: chrono::Duration) -> Self::Output { + Self::Output::from(self.0 + rside) + } +} + +impl std::ops::Sub for Time { + type Output = Time; + fn sub(self, rside: chrono::Duration) -> Self::Output { + Self::Output::from(self.0 - rside) + } +} +*/ + +impl std::ops::Deref for Time { + type Target = chrono::NaiveTime; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for Time { + fn from(value: chrono::NaiveTime) -> Self { + Self(value) + } +} + #[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd)] pub struct Weight(si::Kilogram); @@ -268,4 +328,27 @@ mod test { "1 hours 10 minutes" ); } + + #[test] + fn it_parses_time_values() { + assert_eq!( + Time::parse("13:25"), + Ok(Time::from( + chrono::NaiveTime::from_hms_opt(13, 25, 0).unwrap() + )), + ); + assert_eq!( + Time::parse("13:25:50"), + Ok(Time::from( + chrono::NaiveTime::from_hms_opt(13, 25, 50).unwrap() + )), + ); + } + + #[test] + fn it_formats_time_values() { + let time = Time::from(chrono::NaiveTime::from_hms_opt(13, 25, 50).unwrap()); + assert_eq!(time.format(FormatOption::Abbreviated), "13:25".to_owned()); + assert_eq!(time.format(FormatOption::Full), "13:25:50".to_owned()); + } }