use crate::domain::errors::DomainError;
#[derive(
Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize,
)]
pub struct ScheduledTime {
hour: u32,
minute: u32,
}
impl ScheduledTime {
pub fn new(hour: u32, minute: u32) -> Result<Self, DomainError> {
if hour > 23 || minute > 59 {
return Err(DomainError::InvalidScheduledTime);
}
Ok(Self { hour, minute })
}
pub fn hour(&self) -> u32 {
self.hour
}
pub fn minute(&self) -> u32 {
self.minute
}
}
impl std::fmt::Display for ScheduledTime {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:02}:{:02}", self.hour, self.minute)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new_with_valid_hour_and_minute_returns_scheduled_time() {
let result = ScheduledTime::new(8, 0);
assert!(result.is_ok());
assert_eq!(result.unwrap().to_string(), "08:00");
}
#[test]
fn new_with_invalid_hour_returns_error() {
let result = ScheduledTime::new(24, 0);
assert!(matches!(result, Err(DomainError::InvalidScheduledTime)));
}
#[test]
fn new_with_invalid_minute_returns_error() {
let result = ScheduledTime::new(8, 60);
assert!(matches!(result, Err(DomainError::InvalidScheduledTime)));
}
#[test]
fn display_formats_as_hh_mm() {
let time = ScheduledTime::new(20, 30).unwrap();
assert_eq!(time.to_string(), "20:30");
}
#[test]
fn hour_returns_stored_hour() {
let time = ScheduledTime::new(8, 30).unwrap();
assert_eq!(time.hour(), 8);
}
#[test]
fn minute_returns_stored_minute() {
let time = ScheduledTime::new(8, 30).unwrap();
assert_eq!(time.minute(), 30);
}
#[test]
fn earlier_time_is_less_than_later_time() {
let morning = ScheduledTime::new(8, 0).unwrap();
let evening = ScheduledTime::new(20, 0).unwrap();
assert!(morning < evening);
}
}