diff options
| author | Mikkel Thestrup <mikkel_thestrup@mithe.dk> | 2025-12-09 14:52:58 +0100 |
|---|---|---|
| committer | Mikkel Thestrup <mikkel_thestrup@mithe.dk> | 2025-12-09 17:17:56 +0100 |
| commit | 147125358b66c2bf097ed11f82042e220a730090 (patch) | |
| tree | 2b6957d01a1afb0553996e916faea5c646f5cc6e /src/domain/calendar.rs | |
| parent | 4b1074193991a510fd2129513d5fcb7c6da933d2 (diff) | |
| download | kal-master.tar.gz kal-master.zip | |
- Added `calendar.rs` with Calendar entity and builder
- Added `event.rs` with Event model and builder
- Added `recurrence.rs` for recurrence rules
- Added `mod.rs` to expose domain module structure
These files establish the core domain layer structures
for future business logic.
Diffstat (limited to 'src/domain/calendar.rs')
| -rw-r--r-- | src/domain/calendar.rs | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/src/domain/calendar.rs b/src/domain/calendar.rs new file mode 100644 index 0000000..9e6a7fe --- /dev/null +++ b/src/domain/calendar.rs @@ -0,0 +1,108 @@ +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<String>, + events: BTreeMap<NaiveDate, Vec<Event>>, + is_archived: bool, + created_at: DateTime<Utc>, + updated_at: DateTime<Utc>, +} + +pub struct CalendarBuilder { + name: String, + description: Option<String>, + events: BTreeMap<NaiveDate, Vec<Event>>, + is_archived: bool, +} + +impl CalendarBuilder { + pub fn new(name: String) -> Result<Self, String> { + 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<String>) -> Self { + self.description = description; + self + } + + pub fn events(mut self, events: BTreeMap<NaiveDate, Vec<Event>>) -> 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<Event>) { + 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<String>) { + 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() + } +} |