use crate::domain::value_objects::scheduled_time::ScheduledTime;
#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
pub enum DoseFrequency {
OnceDaily,
TwiceDaily,
ThriceDaily,
EveryXHours(u32), Custom(Vec<ScheduledTime>), }
impl DoseFrequency {
pub fn scheduled_time(&self) -> Vec<ScheduledTime> {
match self {
DoseFrequency::OnceDaily => vec![ScheduledTime::new(8, 0).unwrap()], DoseFrequency::TwiceDaily => vec![
ScheduledTime::new(8, 0).unwrap(), ScheduledTime::new(20, 0).unwrap(), ],
DoseFrequency::ThriceDaily => vec![
ScheduledTime::new(8, 0).unwrap(), ScheduledTime::new(14, 0).unwrap(), ScheduledTime::new(20, 0).unwrap(), ],
DoseFrequency::EveryXHours(_) => vec![], DoseFrequency::Custom(times) => times.clone(),
}
}
pub fn as_str(&self) -> &'static str {
match self {
DoseFrequency::OnceDaily => "OnceDaily",
DoseFrequency::TwiceDaily => "TwiceDaily",
DoseFrequency::ThriceDaily => "ThriceDaily",
DoseFrequency::EveryXHours(_) => "EveryXHours",
DoseFrequency::Custom(_) => "Custom",
}
}
}
impl std::fmt::Display for DoseFrequency {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
DoseFrequency::OnceDaily => write!(f, "Once Daily"),
DoseFrequency::TwiceDaily => write!(f, "Twice Daily"),
DoseFrequency::ThriceDaily => write!(f, "Thrice Daily"),
DoseFrequency::EveryXHours(hours) => write!(f, "Every {} Hours", hours),
DoseFrequency::Custom(times) => {
let times_str = times
.iter()
.map(|t| t.to_string())
.collect::<Vec<String>>()
.join(", ");
write!(f, "Custom ({})", times_str)
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn scheduled_time_once_daily_returns_one_time() {
let freq = DoseFrequency::OnceDaily;
let times = freq.scheduled_time();
let expected_time = ScheduledTime::new(8, 0).unwrap();
assert_eq!(times.len(), 1);
assert_eq!(times[0], expected_time);
}
#[test]
fn scheduled_time_twice_daily_returns_two_times() {
let freq = DoseFrequency::TwiceDaily;
let times = freq.scheduled_time();
let expected_times = vec![
ScheduledTime::new(8, 0).unwrap(),
ScheduledTime::new(20, 0).unwrap(),
];
assert_eq!(times, expected_times);
assert_eq!(times.len(), 2);
}
#[test]
fn display_handles_every_x_hours_and_custom() {
let freq = DoseFrequency::EveryXHours(6);
assert_eq!(freq.to_string(), "Every 6 Hours");
let custom_times = vec![
ScheduledTime::new(9, 0).unwrap(),
ScheduledTime::new(21, 0).unwrap(),
];
let freq_custom = DoseFrequency::Custom(custom_times.clone());
assert!(freq_custom.to_string().contains("Custom"));
assert!(freq_custom.to_string().contains("09:00"));
assert!(freq_custom.to_string().contains("21:00"));
assert!(DoseFrequency::EveryXHours(4).scheduled_time().is_empty());
}
}