From 55c1a6372fd35a466872c3ae2f0d36f2fe66d556 Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Wed, 31 Jan 2024 08:38:17 -0500 Subject: [PATCH] Rename the formatters --- fitnesstrax/app/src/components/weight.rs | 17 ++- fitnesstrax/app/src/types.rs | 133 +++++++++--------- fitnesstrax/app/src/view_models/day_detail.rs | 8 +- 3 files changed, 77 insertions(+), 81 deletions(-) diff --git a/fitnesstrax/app/src/components/weight.rs b/fitnesstrax/app/src/components/weight.rs index 76036c0..2afc259 100644 --- a/fitnesstrax/app/src/components/weight.rs +++ b/fitnesstrax/app/src/components/weight.rs @@ -1,5 +1,5 @@ /* -Copyright 2023, Savanni D'Gerinel +Copyright 2023-2024, Savanni D'Gerinel This file is part of FitnessTrax. @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with Fit use crate::{ components::TextEntry, - types::{FormatOption, Weight}, + types::{FormatOption, WeightFormatter}, }; use gtk::prelude::*; @@ -25,7 +25,7 @@ pub struct WeightLabel { } impl WeightLabel { - pub fn new(weight: Option) -> Self { + pub fn new(weight: Option) -> Self { let label = gtk::Label::builder() .css_classes(["card", "weight-view"]) .can_focus(true) @@ -44,16 +44,19 @@ impl WeightLabel { } } -pub fn weight_editor(weight: Option, on_update: OnUpdate) -> TextEntry +pub fn weight_editor( + weight: Option, + on_update: OnUpdate, +) -> TextEntry where - OnUpdate: Fn(Weight) + 'static, + OnUpdate: Fn(WeightFormatter) + 'static, { TextEntry::new( "0 kg", weight, - |val: &Weight| val.format(FormatOption::Abbreviated), + |val: &WeightFormatter| val.format(FormatOption::Abbreviated), move |v: &str| { - let new_weight = Weight::parse(v); + let new_weight = WeightFormatter::parse(v); match new_weight { Ok(w) => { on_update(w); diff --git a/fitnesstrax/app/src/types.rs b/fitnesstrax/app/src/types.rs index 09a7c71..0411596 100644 --- a/fitnesstrax/app/src/types.rs +++ b/fitnesstrax/app/src/types.rs @@ -57,9 +57,9 @@ pub enum FormatOption { } #[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct Time(chrono::NaiveTime); +pub struct TimeFormatter(chrono::NaiveTime); -impl Time { +impl TimeFormatter { fn format(&self, option: FormatOption) -> String { match option { FormatOption::Abbreviated => self.0.format("%H:%M"), @@ -68,7 +68,7 @@ impl Time { .to_string() } - fn parse(s: &str) -> Result { + fn parse(s: &str) -> Result { let parts = s .split(':') .map(|part| part.parse::().map_err(|_| ParseError)) @@ -76,10 +76,10 @@ impl Time { match parts.len() { 0 => Err(ParseError), 1 => Err(ParseError), - 2 => Ok(Time( + 2 => Ok(TimeFormatter( chrono::NaiveTime::from_hms_opt(parts[0], parts[1], 0).unwrap(), )), - 3 => Ok(Time( + 3 => Ok(TimeFormatter( chrono::NaiveTime::from_hms_opt(parts[0], parts[1], parts[2]).unwrap(), )), _ => Err(ParseError), @@ -87,39 +87,23 @@ impl Time { } } -/* -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 { +impl std::ops::Deref for TimeFormatter { type Target = chrono::NaiveTime; fn deref(&self) -> &Self::Target { &self.0 } } -impl From for Time { +impl From for TimeFormatter { fn from(value: chrono::NaiveTime) -> Self { Self(value) } } #[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd)] -pub struct Weight(si::Kilogram); +pub struct WeightFormatter(si::Kilogram); -impl Weight { +impl WeightFormatter { pub fn format(&self, option: FormatOption) -> String { match option { FormatOption::Abbreviated => format!("{} kg", self.0.value_unsafe), @@ -127,44 +111,44 @@ impl Weight { } } - pub fn parse(s: &str) -> Result { + pub fn parse(s: &str) -> Result { s.parse::() - .map(|w| Weight(w * si::KG)) + .map(|w| WeightFormatter(w * si::KG)) .map_err(|_| ParseError) } } -impl std::ops::Add for Weight { - type Output = Weight; +impl std::ops::Add for WeightFormatter { + type Output = WeightFormatter; fn add(self, rside: Self) -> Self::Output { Self::Output::from(self.0 + rside.0) } } -impl std::ops::Sub for Weight { - type Output = Weight; +impl std::ops::Sub for WeightFormatter { + type Output = WeightFormatter; fn sub(self, rside: Self) -> Self::Output { Self::Output::from(self.0 - rside.0) } } -impl std::ops::Deref for Weight { +impl std::ops::Deref for WeightFormatter { type Target = si::Kilogram; fn deref(&self) -> &Self::Target { &self.0 } } -impl From> for Weight { +impl From> for WeightFormatter { fn from(value: si::Kilogram) -> Self { Self(value) } } #[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd)] -pub struct Distance(si::Meter); +pub struct DistanceFormatter(si::Meter); -impl Distance { +impl DistanceFormatter { pub fn format(&self, option: FormatOption) -> String { match option { FormatOption::Abbreviated => format!("{} km", self.0.value_unsafe / 1000.), @@ -172,43 +156,43 @@ impl Distance { } } - pub fn parse(s: &str) -> Result { + pub fn parse(s: &str) -> Result { let value = s.parse::().map_err(|_| ParseError)?; - Ok(Distance(value * 1000. * si::M)) + Ok(DistanceFormatter(value * 1000. * si::M)) } } -impl std::ops::Add for Distance { - type Output = Distance; +impl std::ops::Add for DistanceFormatter { + type Output = DistanceFormatter; fn add(self, rside: Self) -> Self::Output { Self::Output::from(self.0 + rside.0) } } -impl std::ops::Sub for Distance { - type Output = Distance; +impl std::ops::Sub for DistanceFormatter { + type Output = DistanceFormatter; fn sub(self, rside: Self) -> Self::Output { Self::Output::from(self.0 - rside.0) } } -impl std::ops::Deref for Distance { +impl std::ops::Deref for DistanceFormatter { type Target = si::Meter; fn deref(&self) -> &Self::Target { &self.0 } } -impl From> for Distance { +impl From> for DistanceFormatter { fn from(value: si::Meter) -> Self { Self(value) } } #[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd)] -pub struct Duration(si::Second); +pub struct DurationFormatter(si::Second); -impl Duration { +impl DurationFormatter { pub fn format(&self, option: FormatOption) -> String { let (hours, minutes) = self.hours_and_minutes(); let (h, m) = match option { @@ -222,9 +206,9 @@ impl Duration { } } - pub fn parse(s: &str) -> Result { + pub fn parse(s: &str) -> Result { let value = s.parse::().map_err(|_| ParseError)?; - Ok(Duration(value * 60. * si::S)) + Ok(DurationFormatter(value * 60. * si::S)) } fn hours_and_minutes(&self) -> (i64, i64) { @@ -235,28 +219,28 @@ impl Duration { } } -impl std::ops::Add for Duration { - type Output = Duration; +impl std::ops::Add for DurationFormatter { + type Output = DurationFormatter; fn add(self, rside: Self) -> Self::Output { Self::Output::from(self.0 + rside.0) } } -impl std::ops::Sub for Duration { - type Output = Duration; +impl std::ops::Sub for DurationFormatter { + type Output = DurationFormatter; fn sub(self, rside: Self) -> Self::Output { Self::Output::from(self.0 - rside.0) } } -impl std::ops::Deref for Duration { +impl std::ops::Deref for DurationFormatter { type Target = si::Second; fn deref(&self) -> &Self::Target { &self.0 } } -impl From> for Duration { +impl From> for DurationFormatter { fn from(value: si::Second) -> Self { Self(value) } @@ -277,54 +261,63 @@ mod test { #[test] fn it_parses_weight_values() { - assert_eq!(Weight::parse("15.3"), Ok(Weight(15.3 * si::KG))); - assert_eq!(Weight::parse("15.ab"), Err(ParseError)); + assert_eq!( + WeightFormatter::parse("15.3"), + Ok(WeightFormatter(15.3 * si::KG)) + ); + assert_eq!(WeightFormatter::parse("15.ab"), Err(ParseError)); } #[test] fn it_formats_weight_values() { assert_eq!( - Weight::from(15.3 * si::KG).format(FormatOption::Abbreviated), + WeightFormatter::from(15.3 * si::KG).format(FormatOption::Abbreviated), "15.3 kg" ); assert_eq!( - Weight::from(15.3 * si::KG).format(FormatOption::Full), + WeightFormatter::from(15.3 * si::KG).format(FormatOption::Full), "15.3 kilograms" ); } #[test] fn it_parses_distance_values() { - assert_eq!(Distance::parse("70"), Ok(Distance(70000. * si::M))); - assert_eq!(Distance::parse("15.ab"), Err(ParseError)); + assert_eq!( + DistanceFormatter::parse("70"), + Ok(DistanceFormatter(70000. * si::M)) + ); + assert_eq!(DistanceFormatter::parse("15.ab"), Err(ParseError)); } #[test] fn it_formats_distance_values() { assert_eq!( - Distance::from(70000. * si::M).format(FormatOption::Abbreviated), + DistanceFormatter::from(70000. * si::M).format(FormatOption::Abbreviated), "70 km" ); assert_eq!( - Distance::from(70000. * si::M).format(FormatOption::Full), + DistanceFormatter::from(70000. * si::M).format(FormatOption::Full), "70 kilometers" ); } #[test] fn it_parses_duration_values() { - assert_eq!(Duration::parse("70"), Ok(Duration(4200. * si::S))); - assert_eq!(Duration::parse("15.ab"), Err(ParseError)); + assert_eq!( + DurationFormatter::parse("70"), + Ok(DurationFormatter(4200. * si::S)) + ); + assert_eq!(DurationFormatter::parse("15.ab"), Err(ParseError)); } #[test] fn it_formats_duration_values() { assert_eq!( - Duration::from(4200. * si::S).format(FormatOption::Abbreviated), + DurationFormatter::from(4200. * si::S).format(FormatOption::Abbreviated), "1h 10m" ); assert_eq!( - Duration::from(4200. * si::S).format(FormatOption::Full), + DurationFormatter::from(4200. * si::S).format(FormatOption::Full), "1 hours 10 minutes" ); } @@ -332,14 +325,14 @@ mod test { #[test] fn it_parses_time_values() { assert_eq!( - Time::parse("13:25"), - Ok(Time::from( + TimeFormatter::parse("13:25"), + Ok(TimeFormatter::from( chrono::NaiveTime::from_hms_opt(13, 25, 0).unwrap() )), ); assert_eq!( - Time::parse("13:25:50"), - Ok(Time::from( + TimeFormatter::parse("13:25:50"), + Ok(TimeFormatter::from( chrono::NaiveTime::from_hms_opt(13, 25, 50).unwrap() )), ); @@ -347,7 +340,7 @@ mod test { #[test] fn it_formats_time_values() { - let time = Time::from(chrono::NaiveTime::from_hms_opt(13, 25, 50).unwrap()); + let time = TimeFormatter::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()); } diff --git a/fitnesstrax/app/src/view_models/day_detail.rs b/fitnesstrax/app/src/view_models/day_detail.rs index 98ed4fb..cf8ac0e 100644 --- a/fitnesstrax/app/src/view_models/day_detail.rs +++ b/fitnesstrax/app/src/view_models/day_detail.rs @@ -14,7 +14,7 @@ General Public License for more details. You should have received a copy of the GNU General Public License along with FitnessTrax. If not, see . */ -use crate::{app::App, types::Weight}; +use crate::{app::App, types::WeightFormatter}; use emseries::{Record, RecordId, Recordable}; use ft_core::TraxRecord; use std::{ @@ -124,13 +124,13 @@ impl DayDetailViewModel { } } - pub fn weight(&self) -> Option { + pub fn weight(&self) -> Option { (*self.weight.read().unwrap()) .as_ref() - .map(|w| Weight::from(w.weight)) + .map(|w| WeightFormatter::from(w.weight)) } - pub fn set_weight(&self, new_weight: Weight) { + pub fn set_weight(&self, new_weight: WeightFormatter) { let mut record = self.weight.write().unwrap(); let new_record = match *record { Some(ref rstate) => rstate.clone().with_value(ft_core::Weight {