diff --git a/src/parser/timestamp.rs b/src/parser/timestamp.rs index 4be2845c..ffa9831d 100644 --- a/src/parser/timestamp.rs +++ b/src/parser/timestamp.rs @@ -302,6 +302,109 @@ fn inactive_time_range_timestamp<'b, 'g, 'r, 's>( )) } +pub struct Year(u16); +pub struct Month(u8); +pub struct DayOfMonth(u8); + +impl Year { + // TODO: Make a real error type instead of a boxed any error. + pub fn new<'s>(source: &'s str) -> Result> { + let year = source.parse::()?; + Ok(Year(year)) + } + + pub fn get_value(&self) -> u16 { + self.0 + } +} + +impl Month { + // TODO: Make a real error type instead of a boxed any error. + pub fn new<'s>(source: &'s str) -> Result> { + let month = source.parse::()?; + if month < 1 || month > 12 { + Err("Month exceeds possible range.")?; + } + Ok(Month(month)) + } + + pub fn get_value(&self) -> u8 { + self.0 + } +} + +impl DayOfMonth { + // TODO: Make a real error type instead of a boxed any error. + pub fn new<'s>(source: &'s str) -> Result> { + let day_of_month = source.parse::()?; + if day_of_month < 1 || day_of_month > 31 { + Err("Day of month exceeds possible range.")?; + } + Ok(DayOfMonth(day_of_month)) + } + + pub fn get_value(&self) -> u8 { + self.0 + } +} + +pub struct Date<'s> { + year: Year, + month: Month, + day_of_month: DayOfMonth, + day_name: &'s str, +} + +impl<'s> Date<'s> { + // TODO: Make a real error type instead of a boxed any error. + pub fn new( + year: Year, + month: Month, + day_of_month: DayOfMonth, + day_name: &'s str, + ) -> Result> { + // TODO: Does org-mode support non-gregorian calendars? + // TODO: Do I want to validate leap year? + match (month.get_value(), day_of_month.get_value()) { + (1, 1..=31) => {} + (2, 1..=29) => {} + (3, 1..=31) => {} + (4, 1..=30) => {} + (5, 1..=31) => {} + (6, 1..=30) => {} + (7, 1..=31) => {} + (8, 1..=31) => {} + (9, 1..=30) => {} + (10, 1..=31) => {} + (11, 1..=30) => {} + (12, 1..=31) => {} + _ => Err("Invalid day of month for the month.")?, + }; + Ok(Date { + year, + month, + day_of_month, + day_name, + }) + } + + pub fn get_year(&self) -> &Year { + &self.year + } + + pub fn get_month(&self) -> &Month { + &self.month + } + + pub fn get_day_of_month(&self) -> &DayOfMonth { + &self.day_of_month + } + + pub fn get_day_name(&self) -> &'s str { + self.day_name + } +} + #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] fn date<'b, 'g, 'r, 's>( context: RefContext<'b, 'g, 'r, 's>,