Move the Date struct into types and implement a get_property_numeric.

This commit is contained in:
Tom Alexander
2023-10-02 15:49:51 -04:00
parent 10ae36a419
commit e7ec23af3d
7 changed files with 203 additions and 112 deletions

View File

@@ -54,6 +54,8 @@ pub use object::Bold;
pub use object::Citation;
pub use object::CitationReference;
pub use object::Code;
pub use object::Date;
pub use object::DayOfMonth;
pub use object::Entity;
pub use object::ExportSnippet;
pub use object::FootnoteReference;
@@ -62,6 +64,7 @@ pub use object::InlineSourceBlock;
pub use object::Italic;
pub use object::LatexFragment;
pub use object::LineBreak;
pub use object::Month;
pub use object::Object;
pub use object::OrgMacro;
pub use object::PlainLink;
@@ -79,5 +82,6 @@ pub use object::TimestampRangeType;
pub use object::TimestampType;
pub use object::Underline;
pub use object::Verbatim;
pub use object::Year;
pub(crate) use source::SetSource;
pub use standard_properties::StandardProperties;

View File

@@ -187,6 +187,8 @@ pub struct Timestamp<'s> {
pub source: &'s str,
pub timestamp_type: TimestampType,
pub range_type: TimestampRangeType,
pub start: Option<Date<'s>>,
pub end: Option<Date<'s>>,
}
#[derive(Debug, PartialEq)]
@@ -204,6 +206,115 @@ pub enum TimestampRangeType {
DateRange,
}
#[derive(Debug, PartialEq)]
pub struct Year(u16);
#[derive(Debug, PartialEq)]
pub struct Month(u8);
#[derive(Debug, PartialEq)]
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<Self, Box<dyn std::error::Error>> {
let year = source.parse::<u16>()?;
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<Self, Box<dyn std::error::Error>> {
let month = source.parse::<u8>()?;
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<Self, Box<dyn std::error::Error>> {
let day_of_month = source.parse::<u8>()?;
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
}
}
#[derive(Debug, PartialEq)]
pub struct Date<'s> {
year: Year,
month: Month,
day_of_month: DayOfMonth,
day_name: Option<&'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: Option<&'s str>,
) -> Result<Self, Box<dyn std::error::Error>> {
// 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) -> Option<&'s str> {
self.day_name
}
}
impl<'s> GetStandardProperties<'s> for Object<'s> {
fn get_standard_properties<'b>(&'b self) -> &'b dyn StandardProperties<'s> {
match self {