diff --git a/src/compare/diff.rs b/src/compare/diff.rs index 79288b7..49aa750 100644 --- a/src/compare/diff.rs +++ b/src/compare/diff.rs @@ -43,6 +43,7 @@ use crate::types::GetStandardProperties; use crate::types::GreaterBlock; use crate::types::Heading; use crate::types::HorizontalRule; +use crate::types::Hour; use crate::types::HourInner; use crate::types::InlineBabelCall; use crate::types::InlineSourceBlock; @@ -51,6 +52,7 @@ use crate::types::Keyword; use crate::types::LatexEnvironment; use crate::types::LatexFragment; use crate::types::LineBreak; +use crate::types::Minute; use crate::types::MinuteInner; use crate::types::Month; use crate::types::MonthInner; @@ -81,6 +83,7 @@ use crate::types::Table; use crate::types::TableCell; use crate::types::TableRow; use crate::types::Target; +use crate::types::Time; use crate::types::Timestamp; use crate::types::TimestampRangeType; use crate::types::TimestampType; @@ -2247,6 +2250,58 @@ fn compare_timestamp<'b, 's>( // Compare time start let hour_start: Option = get_property_numeric(emacs, ":hour-start")?; let minute_start: Option = get_property_numeric(emacs, ":minute-start")?; + let rust_hour_start = rust + .start_time + .as_ref() + .map(Time::get_hour) + .map(Hour::get_value); + let rust_minute_start = rust + .start_time + .as_ref() + .map(Time::get_minute) + .map(Minute::get_value); + if hour_start != rust_hour_start { + this_status = DiffStatus::Bad; + message = Some(format!( + "hour start mismatch (emacs != rust) {:?} != {:?}", + hour_start, rust_hour_start + )); + } + if minute_start != rust_minute_start { + this_status = DiffStatus::Bad; + message = Some(format!( + "minute start mismatch (emacs != rust) {:?} != {:?}", + minute_start, rust_minute_start + )); + } + + // Compare time end + let hour_end: Option = get_property_numeric(emacs, ":hour-end")?; + let minute_end: Option = get_property_numeric(emacs, ":minute-end")?; + let rust_hour_end = rust + .end_time + .as_ref() + .map(Time::get_hour) + .map(Hour::get_value); + let rust_minute_end = rust + .end_time + .as_ref() + .map(Time::get_minute) + .map(Minute::get_value); + if hour_end != rust_hour_end { + this_status = DiffStatus::Bad; + message = Some(format!( + "hour end mismatch (emacs != rust) {:?} != {:?}", + hour_end, rust_hour_end + )); + } + if minute_end != rust_minute_end { + this_status = DiffStatus::Bad; + message = Some(format!( + "minute end mismatch (emacs != rust) {:?} != {:?}", + minute_end, rust_minute_end + )); + } // TODO: Compare :hour-start :minute-start :hour-end :minute-end :repeater-type :repeater-value :repeater-unit :warning-type :warning-value :warning-unit // diff --git a/src/parser/timestamp.rs b/src/parser/timestamp.rs index 71ee6f4..e1cabd6 100644 --- a/src/parser/timestamp.rs +++ b/src/parser/timestamp.rs @@ -23,7 +23,10 @@ use crate::error::Res; use crate::parser::util::get_consumed; use crate::types::Date; use crate::types::DayOfMonth; +use crate::types::Hour; +use crate::types::Minute; use crate::types::Month; +use crate::types::Time; use crate::types::Timestamp; use crate::types::TimestampRangeType; use crate::types::TimestampType; @@ -67,6 +70,8 @@ fn diary_timestamp<'b, 'g, 'r, 's>( range_type: TimestampRangeType::None, start: None, end: None, + start_time: None, // TODO + end_time: None, // TODO }, )) } @@ -113,7 +118,7 @@ fn active_timestamp<'b, 'g, 'r, 's>( exit_matcher: &active_time_rest_end, }); let time_context = context.with_additional_node(&time_context); - let (remaining, _time) = + let (remaining, time) = opt(tuple((space1, parser_with_context!(time)(&time_context))))(remaining)?; let (remaining, _repeater) = opt(tuple((space1, parser_with_context!(repeater)(context))))(remaining)?; @@ -135,6 +140,8 @@ fn active_timestamp<'b, 'g, 'r, 's>( range_type: TimestampRangeType::None, start: Some(start.clone()), end: Some(start), + start_time: time.as_ref().map(|(_, time)| time.clone()), + end_time: time.map(|(_, time)| time), }, )) } @@ -151,7 +158,7 @@ fn inactive_timestamp<'b, 'g, 'r, 's>( exit_matcher: &inactive_time_rest_end, }); let time_context = context.with_additional_node(&time_context); - let (remaining, _time) = + let (remaining, time) = opt(tuple((space1, parser_with_context!(time)(&time_context))))(remaining)?; let (remaining, _repeater) = opt(tuple((space1, parser_with_context!(repeater)(context))))(remaining)?; @@ -173,6 +180,8 @@ fn inactive_timestamp<'b, 'g, 'r, 's>( range_type: TimestampRangeType::None, start: Some(start.clone()), end: Some(start), + start_time: time.as_ref().map(|(_, time)| time.clone()), + end_time: time.map(|(_, time)| time), }, )) } @@ -199,6 +208,8 @@ fn active_date_range_timestamp<'b, 'g, 'r, 's>( range_type: TimestampRangeType::DateRange, start: first_timestamp.start, end: second_timestamp.end, + start_time: first_timestamp.start_time, + end_time: second_timestamp.end_time, }, )) } @@ -220,10 +231,10 @@ fn active_time_range_timestamp<'b, 'g, 'r, 's>( exit_matcher: &time_range_rest_end, }); let first_time_context = time_context.with_additional_node(&first_time_context); - let (remaining, _first_time) = + let (remaining, (_, first_time)) = tuple((space1, parser_with_context!(time)(&first_time_context)))(remaining)?; let (remaining, _) = tag("-")(remaining)?; - let (remaining, _second_time) = parser_with_context!(time)(&time_context)(remaining)?; + let (remaining, second_time) = parser_with_context!(time)(&time_context)(remaining)?; let (remaining, _repeater) = opt(tuple((space1, parser_with_context!(repeater)(context))))(remaining)?; let (remaining, _warning_delay) = opt(tuple(( @@ -244,6 +255,8 @@ fn active_time_range_timestamp<'b, 'g, 'r, 's>( range_type: TimestampRangeType::None, start: Some(start_date.clone()), end: Some(start_date), + start_time: Some(first_time), + end_time: Some(second_time), }, )) } @@ -271,6 +284,8 @@ fn inactive_date_range_timestamp<'b, 'g, 'r, 's>( range_type: TimestampRangeType::DateRange, start: first_timestamp.start, end: second_timestamp.end, + start_time: first_timestamp.start_time, + end_time: second_timestamp.end_time, }, )) } @@ -292,10 +307,10 @@ fn inactive_time_range_timestamp<'b, 'g, 'r, 's>( exit_matcher: &time_range_rest_end, }); let first_time_context = time_context.with_additional_node(&first_time_context); - let (remaining, _first_time) = + let (remaining, (_, first_time)) = tuple((space1, parser_with_context!(time)(&first_time_context)))(remaining)?; let (remaining, _) = tag("-")(remaining)?; - let (remaining, _second_time) = parser_with_context!(time)(&time_context)(remaining)?; + let (remaining, second_time) = parser_with_context!(time)(&time_context)(remaining)?; let (remaining, _repeater) = opt(tuple((space1, parser_with_context!(repeater)(context))))(remaining)?; let (remaining, _warning_delay) = opt(tuple(( @@ -316,6 +331,8 @@ fn inactive_time_range_timestamp<'b, 'g, 'r, 's>( range_type: TimestampRangeType::None, start: Some(start_date.clone()), end: Some(start_date), + start_time: Some(first_time), + end_time: Some(second_time), }, )) } @@ -389,16 +406,23 @@ fn dayname_end<'b, 'g, 'r, 's>( fn time<'b, 'g, 'r, 's>( context: RefContext<'b, 'g, 'r, 's>, input: OrgSource<'s>, -) -> Res, OrgSource<'s>> { - let (remaining, _hour) = verify(digit1, |hour: &OrgSource<'_>| { +) -> Res, Time<'s>> { + let (remaining, hour) = verify(digit1, |hour: &OrgSource<'_>| { hour.len() >= 1 && hour.len() <= 2 })(input)?; let (remaining, _) = tag(":")(remaining)?; - let (remaining, _minute) = + let (remaining, minute) = verify(digit1, |minute: &OrgSource<'_>| minute.len() == 2)(remaining)?; let (remaining, _time_rest) = opt(parser_with_context!(time_rest)(context))(remaining)?; - let source = get_consumed(input, remaining); - Ok((remaining, source)) + + let hour = Hour::new(Into::<&str>::into(hour)) + .expect("TODO: I should be able to return CustomError from nom parsers."); + let minute = Minute::new(Into::<&str>::into(minute)) + .expect("TODO: I should be able to return CustomError from nom parsers."); + let time = Time::new(hour, minute, _time_rest.map(Into::<&str>::into)) + .expect("TODO: I should be able to return CustomError from nom parsers."); + + Ok((remaining, time)) } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] diff --git a/src/types/object.rs b/src/types/object.rs index 229e2a9..dd3117a 100644 --- a/src/types/object.rs +++ b/src/types/object.rs @@ -189,6 +189,8 @@ pub struct Timestamp<'s> { pub range_type: TimestampRangeType, pub start: Option>, pub end: Option>, + pub start_time: Option>, + pub end_time: Option>, } #[derive(Debug, PartialEq)] @@ -273,7 +275,7 @@ impl Hour { // TODO: Make a real error type instead of a boxed any error. pub fn new<'s>(source: &'s str) -> Result> { let hour = source.parse::()?; - if hour < 1 || hour > 23 { + if hour > 23 { Err("Hour exceeds possible range.")?; } Ok(Hour(hour)) @@ -288,7 +290,7 @@ impl Minute { // TODO: Make a real error type instead of a boxed any error. pub fn new<'s>(source: &'s str) -> Result> { let minute = source.parse::()?; - if minute < 1 || minute > 59 { + if minute > 59 { Err("Minute exceeds possible range.")?; } Ok(Minute(minute))