Compare date start/end.

This commit is contained in:
Tom Alexander 2023-10-02 15:59:06 -04:00
parent c55fae86f8
commit a8a34e2d9c
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
5 changed files with 115 additions and 46 deletions

View File

@ -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<u16> = get_property_unquoted_atom(emacs, ":year-start")?
.map(|val| val.parse())
.map_or(Ok(None), |r| r.map(Some))?;
let month_start: Option<u8> = 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<u8> = 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::<u16>(emacs, ":year-end")?;
let year_start: Option<YearInner> = get_property_numeric(emacs, ":year-start")?;
let month_start: Option<MonthInner> = get_property_numeric(emacs, ":month-start")?;
let day_of_month_start: Option<DayOfMonthInner> = 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<YearInner> = get_property_numeric(emacs, ":year-end")?;
let month_end: Option<MonthInner> = get_property_numeric(emacs, ":month-end")?;
let day_of_month_end: Option<DayOfMonthInner> = 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

View File

@ -248,11 +248,11 @@ where
<N as FromStr>::Err: std::error::Error,
<N as FromStr>::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::<N>())
.map_or(Ok(None), |r| r.map(Some))?;
Ok(bar)
Ok(parsed_number)
}

View File

@ -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<OrgSource<'s>, 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<OrgSource<'s>, 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<OrgSource<'s>, 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<OrgSource<'s>, 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),
},
))
}

View File

@ -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;

View File

@ -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<Self, Box<dyn std::error::Error>> {
let year = source.parse::<u16>()?;
let year = source.parse::<YearInner>()?;
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<Self, Box<dyn std::error::Error>> {
let month = source.parse::<u8>()?;
let month = source.parse::<MonthInner>()?;
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<Self, Box<dyn std::error::Error>> {
let day_of_month = source.parse::<u8>()?;
let day_of_month = source.parse::<DayOfMonthInner>()?;
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,