use std::collections::BTreeMap; use chrono::{DateTime, NaiveDate, Utc}; use getset::Getters; use uuid::Uuid; use crate::domain::Event; #[derive(Clone, Debug, Getters)] #[getset(get = "pub")] pub struct Calendar { id: Uuid, name: String, description: Option, events: BTreeMap>, is_archived: bool, created_at: DateTime, updated_at: DateTime, } pub struct CalendarBuilder { name: String, description: Option, events: BTreeMap>, is_archived: bool, } impl CalendarBuilder { pub fn new(name: String) -> Result { if name.is_empty() { Err("Name cannot be empty".to_string()) } else { Ok(Self { name, description: None, events: BTreeMap::new(), is_archived: false }) } } pub fn description(mut self, description: Option) -> Self { self.description = description; self } pub fn events(mut self, events: BTreeMap>) -> Self { self.events = events; self } pub fn is_archived(mut self, is_archived: bool) -> Self { self.is_archived = is_archived; self } pub fn build(self) -> Calendar { let now = Utc::now(); Calendar { id: Uuid::new_v4(), name: self.name, description: self.description, events: self.events, is_archived: self.is_archived, created_at: now, updated_at: now } } } impl Calendar { pub fn add_events(&mut self, events: Vec) { for event in events { let date = event.start().date_naive(); self.events .entry(date) .or_insert_with(Vec::new) .push(event); } self.touch() } pub fn update_name(&mut self, name: String) -> Result<(), String> { if name.is_empty() { Err("Name cannot be empty".to_string()) } else { self.name = name; self.touch(); Ok(()) } } pub fn update_description(&mut self, description: Option) { self.description = description; self.touch() } pub fn update_archived(&mut self, is_archived: bool) { self.is_archived = is_archived; self.touch() } pub fn touch(&mut self) { self.updated_at = Utc::now() } }