From a8a34e2d9c164bcea57c0fb355e90d5bdd8ab0c7 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Mon, 2 Oct 2023 15:59:06 -0400 Subject: [PATCH] Compare date start/end. --- src/compare/diff.rs | 86 +++++++++++++++++++++++++++++++++++------ src/compare/util.rs | 6 +-- src/parser/timestamp.rs | 36 ++++++++--------- src/types/mod.rs | 3 ++ src/types/object.rs | 30 +++++++------- 5 files changed, 115 insertions(+), 46 deletions(-) diff --git a/src/compare/diff.rs b/src/compare/diff.rs index f0a1b8d4..98a7bdcd 100644 --- a/src/compare/diff.rs +++ b/src/compare/diff.rs @@ -24,6 +24,9 @@ use crate::types::Clock; use crate::types::Code; use crate::types::Comment; use crate::types::CommentBlock; +use crate::types::Date; +use crate::types::DayOfMonth; +use crate::types::DayOfMonthInner; use crate::types::DiarySexp; use crate::types::Document; use crate::types::DocumentElement; @@ -47,6 +50,8 @@ use crate::types::Keyword; use crate::types::LatexEnvironment; use crate::types::LatexFragment; use crate::types::LineBreak; +use crate::types::Month; +use crate::types::MonthInner; use crate::types::NodeProperty; use crate::types::OrgMacro; use crate::types::Paragraph; @@ -81,6 +86,8 @@ use crate::types::TodoKeywordType; use crate::types::Underline; use crate::types::Verbatim; use crate::types::VerseBlock; +use crate::types::Year; +use crate::types::YearInner; #[derive(Debug)] pub enum DiffEntry<'b, 's> { @@ -2165,21 +2172,76 @@ fn compare_timestamp<'b, 's>( } // Compare start - let year_start: Option = get_property_unquoted_atom(emacs, ":year-start")? - .map(|val| val.parse()) - .map_or(Ok(None), |r| r.map(Some))?; - let month_start: Option = get_property_unquoted_atom(emacs, ":month-start")? - .map(|val| val.parse()) - .map_or(Ok(None), |r| r.map(Some))?; - let day_of_month_start: Option = get_property_unquoted_atom(emacs, ":day-start")? - .map(|val| val.parse()) - .map_or(Ok(None), |r| r.map(Some))?; - - let year_end = get_property_numeric::(emacs, ":year-end")?; + let year_start: Option = get_property_numeric(emacs, ":year-start")?; + let month_start: Option = get_property_numeric(emacs, ":month-start")?; + let day_of_month_start: Option = get_property_numeric(emacs, ":day-start")?; + let rust_year_start = rust.start.as_ref().map(Date::get_year).map(Year::get_value); + let rust_month_start = rust + .start + .as_ref() + .map(Date::get_month) + .map(Month::get_value); + let rust_day_of_month_start = rust + .start + .as_ref() + .map(Date::get_day_of_month) + .map(DayOfMonth::get_value); + if year_start != rust_year_start { + this_status = DiffStatus::Bad; + message = Some(format!( + "year start mismatch (emacs != rust) {:?} != {:?}", + year_start, rust_year_start + )); + } + if month_start != rust_month_start { + this_status = DiffStatus::Bad; + message = Some(format!( + "month start mismatch (emacs != rust) {:?} != {:?}", + month_start, rust_month_start + )); + } + if day_of_month_start != rust_day_of_month_start { + this_status = DiffStatus::Bad; + message = Some(format!( + "day of month start mismatch (emacs != rust) {:?} != {:?}", + day_of_month_start, rust_day_of_month_start + )); + } // Compare end + let year_end: Option = get_property_numeric(emacs, ":year-end")?; + let month_end: Option = get_property_numeric(emacs, ":month-end")?; + let day_of_month_end: Option = get_property_numeric(emacs, ":day-end")?; + let rust_year_end = rust.end.as_ref().map(Date::get_year).map(Year::get_value); + let rust_month_end = rust.end.as_ref().map(Date::get_month).map(Month::get_value); + let rust_day_of_month_end = rust + .end + .as_ref() + .map(Date::get_day_of_month) + .map(DayOfMonth::get_value); + if year_end != rust_year_end { + this_status = DiffStatus::Bad; + message = Some(format!( + "year end mismatch (emacs != rust) {:?} != {:?}", + year_end, rust_year_end + )); + } + if month_end != rust_month_end { + this_status = DiffStatus::Bad; + message = Some(format!( + "month end mismatch (emacs != rust) {:?} != {:?}", + month_end, rust_month_end + )); + } + if day_of_month_end != rust_day_of_month_end { + this_status = DiffStatus::Bad; + message = Some(format!( + "day of month end mismatch (emacs != rust) {:?} != {:?}", + day_of_month_end, rust_day_of_month_end + )); + } - // TODO: Compare :year-start :month-start :day-start :hour-start :minute-start :year-end :month-end :day-end :hour-end :minute-end :repeater-type :repeater-value :repeater-unit :warning-type :warning-value :warning-unit + // TODO: Compare :hour-start :minute-start :hour-end :minute-end :repeater-type :repeater-value :repeater-unit :warning-type :warning-value :warning-unit // // :type unquoted atom either diary, active, inactive, active-range, or inactive-range. // :range-type unquoted atom either nil, daterange diff --git a/src/compare/util.rs b/src/compare/util.rs index 0a96f49f..afaedf35 100644 --- a/src/compare/util.rs +++ b/src/compare/util.rs @@ -248,11 +248,11 @@ where ::Err: std::error::Error, ::Err: 's, { - let foo = get_property(emacs, key)? + let unparsed_string = get_property(emacs, key)? .map(Token::as_atom) .map_or(Ok(None), |r| r.map(Some))?; - let bar = foo + let parsed_number = unparsed_string .map(|val| val.parse::()) .map_or(Ok(None), |r| r.map(Some))?; - Ok(bar) + Ok(parsed_number) } diff --git a/src/parser/timestamp.rs b/src/parser/timestamp.rs index 20d1a4c1..71ee6f43 100644 --- a/src/parser/timestamp.rs +++ b/src/parser/timestamp.rs @@ -133,8 +133,8 @@ fn active_timestamp<'b, 'g, 'r, 's>( source: source.into(), timestamp_type: TimestampType::Active, range_type: TimestampRangeType::None, - start: Some(start), - end: None, + start: Some(start.clone()), + end: Some(start), }, )) } @@ -171,8 +171,8 @@ fn inactive_timestamp<'b, 'g, 'r, 's>( source: source.into(), timestamp_type: TimestampType::Inactive, range_type: TimestampRangeType::None, - start: Some(start), - end: None, + start: Some(start.clone()), + end: Some(start), }, )) } @@ -182,10 +182,10 @@ fn active_date_range_timestamp<'b, 'g, 'r, 's>( context: RefContext<'b, 'g, 'r, 's>, input: OrgSource<'s>, ) -> Res, Timestamp<'s>> { - let (remaining, _first_timestamp) = active_timestamp(context, input)?; + let (remaining, first_timestamp) = active_timestamp(context, input)?; // TODO: Does the space0 at the end of the active/inactive timestamp parsers cause this to be incorrect? I could use a look-behind to make sure the preceding character is not whitespace let (remaining, _separator) = tag("--")(remaining)?; - let (remaining, _second_timestamp) = active_timestamp(context, remaining)?; + let (remaining, second_timestamp) = active_timestamp(context, remaining)?; let (remaining, _trailing_whitespace) = maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?; @@ -197,8 +197,8 @@ fn active_date_range_timestamp<'b, 'g, 'r, 's>( source: source.into(), timestamp_type: TimestampType::ActiveRange, range_type: TimestampRangeType::DateRange, - start: None, // TODO - end: None, // TODO + start: first_timestamp.start, + end: second_timestamp.end, }, )) } @@ -209,7 +209,7 @@ fn active_time_range_timestamp<'b, 'g, 'r, 's>( input: OrgSource<'s>, ) -> Res, Timestamp<'s>> { let (remaining, _) = tag("<")(input)?; - let (remaining, _date) = date(context, remaining)?; + let (remaining, start_date) = date(context, remaining)?; let time_context = ContextElement::ExitMatcherNode(ExitMatcherNode { class: ExitClass::Gamma, exit_matcher: &active_time_rest_end, @@ -242,8 +242,8 @@ fn active_time_range_timestamp<'b, 'g, 'r, 's>( source: source.into(), timestamp_type: TimestampType::Active, range_type: TimestampRangeType::None, - start: None, // TODO - end: None, // TODO + start: Some(start_date.clone()), + end: Some(start_date), }, )) } @@ -253,10 +253,10 @@ fn inactive_date_range_timestamp<'b, 'g, 'r, 's>( context: RefContext<'b, 'g, 'r, 's>, input: OrgSource<'s>, ) -> Res, Timestamp<'s>> { - let (remaining, _first_timestamp) = inactive_timestamp(context, input)?; + let (remaining, first_timestamp) = inactive_timestamp(context, input)?; // TODO: Does the space0 at the end of the active/inactive timestamp parsers cause this to be incorrect? I could use a look-behind to make sure the preceding character is not whitespace let (remaining, _separator) = tag("--")(remaining)?; - let (remaining, _second_timestamp) = inactive_timestamp(context, remaining)?; + let (remaining, second_timestamp) = inactive_timestamp(context, remaining)?; let (remaining, _trailing_whitespace) = maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?; @@ -269,8 +269,8 @@ fn inactive_date_range_timestamp<'b, 'g, 'r, 's>( timestamp_type: TimestampType::InactiveRange, range_type: TimestampRangeType::DateRange, - start: None, // TODO - end: None, // TODO + start: first_timestamp.start, + end: second_timestamp.end, }, )) } @@ -281,7 +281,7 @@ fn inactive_time_range_timestamp<'b, 'g, 'r, 's>( input: OrgSource<'s>, ) -> Res, Timestamp<'s>> { let (remaining, _) = tag("[")(input)?; - let (remaining, _date) = date(context, remaining)?; + let (remaining, start_date) = date(context, remaining)?; let time_context = ContextElement::ExitMatcherNode(ExitMatcherNode { class: ExitClass::Gamma, exit_matcher: &inactive_time_rest_end, @@ -314,8 +314,8 @@ fn inactive_time_range_timestamp<'b, 'g, 'r, 's>( source: source.into(), timestamp_type: TimestampType::Inactive, range_type: TimestampRangeType::None, - start: None, // TODO - end: None, // TODO + start: Some(start_date.clone()), + end: Some(start_date), }, )) } diff --git a/src/types/mod.rs b/src/types/mod.rs index bb10ca42..13fc8db5 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -56,6 +56,7 @@ pub use object::CitationReference; pub use object::Code; pub use object::Date; pub use object::DayOfMonth; +pub use object::DayOfMonthInner; pub use object::Entity; pub use object::ExportSnippet; pub use object::FootnoteReference; @@ -65,6 +66,7 @@ pub use object::Italic; pub use object::LatexFragment; pub use object::LineBreak; pub use object::Month; +pub use object::MonthInner; pub use object::Object; pub use object::OrgMacro; pub use object::PlainLink; @@ -83,5 +85,6 @@ pub use object::TimestampType; pub use object::Underline; pub use object::Verbatim; pub use object::Year; +pub use object::YearInner; pub(crate) use source::SetSource; pub use standard_properties::StandardProperties; diff --git a/src/types/object.rs b/src/types/object.rs index b16cfb60..dcc72bcd 100644 --- a/src/types/object.rs +++ b/src/types/object.rs @@ -206,23 +206,27 @@ pub enum TimestampRangeType { DateRange, } -#[derive(Debug, PartialEq)] -pub struct Year(u16); +pub type YearInner = u16; +pub type MonthInner = u8; +pub type DayOfMonthInner = u8; -#[derive(Debug, PartialEq)] -pub struct Month(u8); +#[derive(Debug, PartialEq, Clone)] +pub struct Year(YearInner); -#[derive(Debug, PartialEq)] -pub struct DayOfMonth(u8); +#[derive(Debug, PartialEq, Clone)] +pub struct Month(MonthInner); + +#[derive(Debug, PartialEq, Clone)] +pub struct DayOfMonth(DayOfMonthInner); 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::()?; + let year = source.parse::()?; Ok(Year(year)) } - pub fn get_value(&self) -> u16 { + pub fn get_value(&self) -> YearInner { self.0 } } @@ -230,14 +234,14 @@ impl Year { 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::()?; + let month = source.parse::()?; if month < 1 || month > 12 { Err("Month exceeds possible range.")?; } Ok(Month(month)) } - pub fn get_value(&self) -> u8 { + pub fn get_value(&self) -> MonthInner { self.0 } } @@ -245,19 +249,19 @@ impl Month { 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::()?; + 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 { + pub fn get_value(&self) -> DayOfMonthInner { self.0 } } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub struct Date<'s> { year: Year, month: Month,