diff --git a/src/lib.rs b/src/lib.rs index e142d69..7cb2af2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,102 @@ -use crate::session_date_calculator::Day; -use chrono::Weekday; +use crate::session_date_calculator::{Day, NthWeekday}; +use chrono::{NaiveDate, Weekday}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; pub mod session_date_calculator; pub mod webpage; +#[derive(Debug, Clone)] +pub struct DatedSession { + pub day: Day, + pub session: Session, + pub applying_exception: Option, +} + +impl Noted for DatedSession { + fn note(&self) -> Option<&String> { + match &self.applying_exception { + Some(e) => e.note(), + None => self.session.note(), + } + } +} + +#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] +pub enum Session { + Regular { + rule: NthWeekday, + note: Option, + except: HashMap, + }, + Extra { + date: NaiveDate, + note: Option, + }, +} + +impl Session { + pub fn into_dated(self, day: Day) -> Result { + if !self.is_applicable_to(&day) { + return Err(self); + } + + let dated_session = DatedSession { + applying_exception: match self { + Session::Regular { ref except, .. } => except.get(&day.date).cloned(), + _ => None, + }, + session: self, + day, + }; + Ok(dated_session) + } + + pub fn is_applicable_to(&self, day: &Day) -> bool { + match *self { + Session::Regular { rule, .. } => rule.matches(day), + Session::Extra { date, .. } => day.date == date, + } + } +} + +impl Noted for Session { + fn note(&self) -> Option<&String> { + match self { + Session::Regular { note, .. } => note, + Session::Extra { note, .. } => note, + } + .as_ref() + } +} + +#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] +pub enum Exception { + Cancel { + note: Option, + }, + Alter { + #[serde(default)] + date: Option, + #[serde(default)] + note: Option, + }, +} + +impl Noted for Exception { + fn note(&self) -> Option<&String> { + match self { + Exception::Cancel { note, .. } => note, + Exception::Alter { note, .. } => note, + } + .as_ref() + } +} + +pub trait Noted { + fn note(&self) -> Option<&String>; +} + pub fn localize_day(day: &Day) -> String { format!( "{}, {}", @@ -18,4 +111,4 @@ pub fn localize_day(day: &Day) -> String { }, day.date.format("%d.%m.%Y") ) -} \ No newline at end of file +} diff --git a/src/session_date_calculator.rs b/src/session_date_calculator.rs index 01f1b7f..3d1e396 100644 --- a/src/session_date_calculator.rs +++ b/src/session_date_calculator.rs @@ -5,7 +5,7 @@ use std::fmt::{Display, Formatter}; use std::num::ParseIntError; use std::str::FromStr; -#[derive(Debug, Copy, Clone, Serialize, Deserialize)] +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] pub struct NthWeekday { pub n: u8, pub weekday: Weekday, diff --git a/styles.css b/styles.css index ff5e3d3..35db1f9 100644 --- a/styles.css +++ b/styles.css @@ -5,7 +5,7 @@ --white: white; --black: black; --red: red; - --yellow: #f0f00f; + --yellow: #bbbb11; --green: #1fd51f; } ul { @@ -70,6 +70,9 @@ html, body { .highlight-background { background-color: var(--green); } -.red-text { - color: var(--red); -} \ No newline at end of file +.cancel-background { + background-color: var(--red); +} +.change-background { + background-color: var(--yellow); +}