Compare warning delay and repeater.

This commit is contained in:
Tom Alexander 2023-10-02 18:58:30 -04:00
parent 512432c5f0
commit 6a8ae9d838
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
4 changed files with 235 additions and 53 deletions

View File

@ -72,6 +72,8 @@ use crate::types::PropertyDrawer;
use crate::types::RadioLink; use crate::types::RadioLink;
use crate::types::RadioTarget; use crate::types::RadioTarget;
use crate::types::RegularLink; use crate::types::RegularLink;
use crate::types::RepeaterType;
use crate::types::RepeaterWarningDelayValueType;
use crate::types::Section; use crate::types::Section;
use crate::types::SrcBlock; use crate::types::SrcBlock;
use crate::types::StandardProperties; use crate::types::StandardProperties;
@ -84,6 +86,7 @@ use crate::types::TableCell;
use crate::types::TableRow; use crate::types::TableRow;
use crate::types::Target; use crate::types::Target;
use crate::types::Time; use crate::types::Time;
use crate::types::TimeUnit;
use crate::types::Timestamp; use crate::types::Timestamp;
use crate::types::TimestampRangeType; use crate::types::TimestampRangeType;
use crate::types::TimestampType; use crate::types::TimestampType;
@ -91,6 +94,7 @@ use crate::types::TodoKeywordType;
use crate::types::Underline; use crate::types::Underline;
use crate::types::Verbatim; use crate::types::Verbatim;
use crate::types::VerseBlock; use crate::types::VerseBlock;
use crate::types::WarningDelayType;
use crate::types::Year; use crate::types::Year;
use crate::types::YearInner; use crate::types::YearInner;
@ -2304,18 +2308,104 @@ fn compare_timestamp<'b, 's>(
)); ));
} }
// TODO: Compare :repeater-type :repeater-value :repeater-unit :warning-type :warning-value :warning-unit // Compare repeater
// let repeater_type = get_property_unquoted_atom(emacs, ":repeater-type")?;
// :type unquoted atom either diary, active, inactive, active-range, or inactive-range. let repeater_value: Option<RepeaterWarningDelayValueType> =
// :range-type unquoted atom either nil, daterange get_property_numeric(emacs, ":repeater-value")?;
// :raw-value quoted string of the source let repeater_unit = get_property_unquoted_atom(emacs, ":repeater-unit")?;
// :*-start :*-end unquoted integers let rust_repeater_type = rust
// :repeater-type optional unquoted atom with value cumulate .repeater
// :repeater-value unquoted integer .as_ref()
// :repeater-unit unquoted atom with value week .map(|repeater| &repeater.repeater_type);
// :warning-type optional unquoted atom with value all let rust_repeater_value = rust.repeater.as_ref().map(|repeater| repeater.value);
// :warning-value unquoted integer let rust_repeater_unit = rust.repeater.as_ref().map(|repeater| &repeater.unit);
// :warning-unit unquoted atom with value day match (repeater_type, rust_repeater_type) {
(Some("cumulate"), Some(RepeaterType::Cumulative)) => {}
(Some("catch-up"), Some(RepeaterType::CatchUp)) => {}
(Some("restart"), Some(RepeaterType::Restart)) => {}
(None, None) => {}
_ => {
this_status = DiffStatus::Bad;
message = Some(format!(
"Repeater type mismatch (emacs != rust) {:?} != {:?}",
repeater_type, rust_repeater_type
));
}
}
if repeater_value != rust_repeater_value {
this_status = DiffStatus::Bad;
message = Some(format!(
"Repeater value mismatch (emacs != rust) {:?} != {:?}",
repeater_value, rust_repeater_value
));
}
match (repeater_unit, rust_repeater_unit) {
(Some("hour"), Some(TimeUnit::Hour)) => {}
(Some("day"), Some(TimeUnit::Day)) => {}
(Some("week"), Some(TimeUnit::Week)) => {}
(Some("month"), Some(TimeUnit::Month)) => {}
(Some("year"), Some(TimeUnit::Year)) => {}
(None, None) => {}
_ => {
this_status = DiffStatus::Bad;
message = Some(format!(
"Repeater unit mismatch (emacs != rust) {:?} != {:?}",
repeater_unit, rust_repeater_unit
));
}
}
// Compare warning_delay
let warning_delay_type = get_property_unquoted_atom(emacs, ":warning-type")?;
let warning_delay_value: Option<RepeaterWarningDelayValueType> =
get_property_numeric(emacs, ":warning-value")?;
let warning_delay_unit = get_property_unquoted_atom(emacs, ":warning-unit")?;
let rust_warning_delay_type = rust
.warning_delay
.as_ref()
.map(|warning_delay| &warning_delay.warning_delay_type);
let rust_warning_delay_value = rust
.warning_delay
.as_ref()
.map(|warning_delay| warning_delay.value);
let rust_warning_delay_unit = rust
.warning_delay
.as_ref()
.map(|warning_delay| &warning_delay.unit);
match (warning_delay_type, rust_warning_delay_type) {
(Some("all"), Some(WarningDelayType::All)) => {}
(Some("first"), Some(WarningDelayType::First)) => {}
(None, None) => {}
_ => {
this_status = DiffStatus::Bad;
message = Some(format!(
"Warning delay type mismatch (emacs != rust) {:?} != {:?}",
warning_delay_type, rust_warning_delay_type
));
}
}
if warning_delay_value != rust_warning_delay_value {
this_status = DiffStatus::Bad;
message = Some(format!(
"Warning delay value mismatch (emacs != rust) {:?} != {:?}",
warning_delay_value, rust_warning_delay_value
));
}
match (warning_delay_unit, rust_warning_delay_unit) {
(Some("hour"), Some(TimeUnit::Hour)) => {}
(Some("day"), Some(TimeUnit::Day)) => {}
(Some("week"), Some(TimeUnit::Week)) => {}
(Some("month"), Some(TimeUnit::Month)) => {}
(Some("year"), Some(TimeUnit::Year)) => {}
(None, None) => {}
_ => {
this_status = DiffStatus::Bad;
message = Some(format!(
"Warning delay unit mismatch (emacs != rust) {:?} != {:?}",
warning_delay_unit, rust_warning_delay_unit
));
}
}
Ok(DiffResult { Ok(DiffResult {
status: this_status, status: this_status,

View File

@ -1,10 +1,10 @@
use nom::branch::alt; use nom::branch::alt;
use nom::bytes::complete::tag; use nom::bytes::complete::tag;
use nom::character::complete::anychar; use nom::character::complete::anychar;
use nom::character::complete::digit0;
use nom::character::complete::digit1; use nom::character::complete::digit1;
use nom::character::complete::one_of; use nom::character::complete::one_of;
use nom::character::complete::space1; use nom::character::complete::space1;
use nom::combinator::map;
use nom::combinator::opt; use nom::combinator::opt;
use nom::combinator::recognize; use nom::combinator::recognize;
use nom::combinator::verify; use nom::combinator::verify;
@ -26,10 +26,15 @@ use crate::types::DayOfMonth;
use crate::types::Hour; use crate::types::Hour;
use crate::types::Minute; use crate::types::Minute;
use crate::types::Month; use crate::types::Month;
use crate::types::Repeater;
use crate::types::RepeaterType;
use crate::types::Time; use crate::types::Time;
use crate::types::TimeUnit;
use crate::types::Timestamp; use crate::types::Timestamp;
use crate::types::TimestampRangeType; use crate::types::TimestampRangeType;
use crate::types::TimestampType; use crate::types::TimestampType;
use crate::types::WarningDelay;
use crate::types::WarningDelayType;
use crate::types::Year; use crate::types::Year;
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
@ -70,8 +75,10 @@ fn diary_timestamp<'b, 'g, 'r, 's>(
range_type: TimestampRangeType::None, range_type: TimestampRangeType::None,
start: None, start: None,
end: None, end: None,
start_time: None, // TODO start_time: None,
end_time: None, // TODO end_time: None,
repeater: None,
warning_delay: None,
}, },
)) ))
} }
@ -122,9 +129,9 @@ fn active_timestamp<'b, 'g, 'r, 's>(
space1, space1,
parser_with_context!(time(true))(&time_context), parser_with_context!(time(true))(&time_context),
)))(remaining)?; )))(remaining)?;
let (remaining, _repeater) = let (remaining, repeater) =
opt(tuple((space1, parser_with_context!(repeater)(context))))(remaining)?; opt(tuple((space1, parser_with_context!(repeater)(context))))(remaining)?;
let (remaining, _warning_delay) = opt(tuple(( let (remaining, warning_delay) = opt(tuple((
space1, space1,
parser_with_context!(warning_delay)(context), parser_with_context!(warning_delay)(context),
)))(remaining)?; )))(remaining)?;
@ -144,6 +151,8 @@ fn active_timestamp<'b, 'g, 'r, 's>(
end: Some(start), end: Some(start),
start_time: time.as_ref().map(|(_, time)| time.clone()), start_time: time.as_ref().map(|(_, time)| time.clone()),
end_time: time.map(|(_, time)| time), end_time: time.map(|(_, time)| time),
repeater: repeater.map(|(_, repeater)| repeater),
warning_delay: warning_delay.map(|(_, warning_delay)| warning_delay),
}, },
)) ))
} }
@ -164,9 +173,9 @@ fn inactive_timestamp<'b, 'g, 'r, 's>(
space1, space1,
parser_with_context!(time(true))(&time_context), parser_with_context!(time(true))(&time_context),
)))(remaining)?; )))(remaining)?;
let (remaining, _repeater) = let (remaining, repeater) =
opt(tuple((space1, parser_with_context!(repeater)(context))))(remaining)?; opt(tuple((space1, parser_with_context!(repeater)(context))))(remaining)?;
let (remaining, _warning_delay) = opt(tuple(( let (remaining, warning_delay) = opt(tuple((
space1, space1,
parser_with_context!(warning_delay)(context), parser_with_context!(warning_delay)(context),
)))(remaining)?; )))(remaining)?;
@ -186,6 +195,8 @@ fn inactive_timestamp<'b, 'g, 'r, 's>(
end: Some(start), end: Some(start),
start_time: time.as_ref().map(|(_, time)| time.clone()), start_time: time.as_ref().map(|(_, time)| time.clone()),
end_time: time.map(|(_, time)| time), end_time: time.map(|(_, time)| time),
repeater: repeater.map(|(_, repeater)| repeater),
warning_delay: warning_delay.map(|(_, warning_delay)| warning_delay),
}, },
)) ))
} }
@ -214,6 +225,10 @@ fn active_date_range_timestamp<'b, 'g, 'r, 's>(
end: second_timestamp.end, end: second_timestamp.end,
start_time: first_timestamp.start_time, start_time: first_timestamp.start_time,
end_time: second_timestamp.end_time, end_time: second_timestamp.end_time,
repeater: first_timestamp.repeater.or(second_timestamp.repeater),
warning_delay: first_timestamp
.warning_delay
.or(second_timestamp.warning_delay),
}, },
)) ))
} }
@ -241,9 +256,9 @@ fn active_time_range_timestamp<'b, 'g, 'r, 's>(
))(remaining)?; ))(remaining)?;
let (remaining, _) = tag("-")(remaining)?; let (remaining, _) = tag("-")(remaining)?;
let (remaining, second_time) = parser_with_context!(time(true))(&time_context)(remaining)?; let (remaining, second_time) = parser_with_context!(time(true))(&time_context)(remaining)?;
let (remaining, _repeater) = let (remaining, repeater) =
opt(tuple((space1, parser_with_context!(repeater)(context))))(remaining)?; opt(tuple((space1, parser_with_context!(repeater)(context))))(remaining)?;
let (remaining, _warning_delay) = opt(tuple(( let (remaining, warning_delay) = opt(tuple((
space1, space1,
parser_with_context!(warning_delay)(context), parser_with_context!(warning_delay)(context),
)))(remaining)?; )))(remaining)?;
@ -263,6 +278,8 @@ fn active_time_range_timestamp<'b, 'g, 'r, 's>(
end: Some(start_date), end: Some(start_date),
start_time: Some(first_time), start_time: Some(first_time),
end_time: Some(second_time), end_time: Some(second_time),
repeater: repeater.map(|(_, repeater)| repeater),
warning_delay: warning_delay.map(|(_, warning_delay)| warning_delay),
}, },
)) ))
} }
@ -292,6 +309,10 @@ fn inactive_date_range_timestamp<'b, 'g, 'r, 's>(
end: second_timestamp.end, end: second_timestamp.end,
start_time: first_timestamp.start_time, start_time: first_timestamp.start_time,
end_time: second_timestamp.end_time, end_time: second_timestamp.end_time,
repeater: first_timestamp.repeater.or(second_timestamp.repeater),
warning_delay: first_timestamp
.warning_delay
.or(second_timestamp.warning_delay),
}, },
)) ))
} }
@ -319,9 +340,9 @@ fn inactive_time_range_timestamp<'b, 'g, 'r, 's>(
))(remaining)?; ))(remaining)?;
let (remaining, _) = tag("-")(remaining)?; let (remaining, _) = tag("-")(remaining)?;
let (remaining, second_time) = parser_with_context!(time(true))(&time_context)(remaining)?; let (remaining, second_time) = parser_with_context!(time(true))(&time_context)(remaining)?;
let (remaining, _repeater) = let (remaining, repeater) =
opt(tuple((space1, parser_with_context!(repeater)(context))))(remaining)?; opt(tuple((space1, parser_with_context!(repeater)(context))))(remaining)?;
let (remaining, _warning_delay) = opt(tuple(( let (remaining, warning_delay) = opt(tuple((
space1, space1,
parser_with_context!(warning_delay)(context), parser_with_context!(warning_delay)(context),
)))(remaining)?; )))(remaining)?;
@ -341,6 +362,8 @@ fn inactive_time_range_timestamp<'b, 'g, 'r, 's>(
end: Some(start_date), end: Some(start_date),
start_time: Some(first_time), start_time: Some(first_time),
end_time: Some(second_time), end_time: Some(second_time),
repeater: repeater.map(|(_, repeater)| repeater),
warning_delay: warning_delay.map(|(_, warning_delay)| warning_delay),
}, },
)) ))
} }
@ -460,32 +483,18 @@ fn time_rest<'b, 'g, 'r, 's>(
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn active_time_rest_end<'b, 'g, 'r, 's>( fn active_time_rest_end<'b, 'g, 'r, 's>(
context: RefContext<'b, 'g, 'r, 's>, _context: RefContext<'b, 'g, 'r, 's>,
input: OrgSource<'s>, input: OrgSource<'s>,
) -> Res<OrgSource<'s>, OrgSource<'s>> { ) -> Res<OrgSource<'s>, OrgSource<'s>> {
alt(( recognize(verify(anychar, |c| ">\n".contains(*c)))(input)
recognize(verify(anychar, |c| ">\n".contains(*c))),
recognize(tuple((space1, parser_with_context!(repeater)(context)))),
recognize(tuple((
space1,
parser_with_context!(warning_delay)(context),
))),
))(input)
} }
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn inactive_time_rest_end<'b, 'g, 'r, 's>( fn inactive_time_rest_end<'b, 'g, 'r, 's>(
context: RefContext<'b, 'g, 'r, 's>, _context: RefContext<'b, 'g, 'r, 's>,
input: OrgSource<'s>, input: OrgSource<'s>,
) -> Res<OrgSource<'s>, OrgSource<'s>> { ) -> Res<OrgSource<'s>, OrgSource<'s>> {
alt(( recognize(verify(anychar, |c| "]\n".contains(*c)))(input)
recognize(verify(anychar, |c| "]\n".contains(*c))),
recognize(tuple((space1, parser_with_context!(repeater)(context)))),
recognize(tuple((
space1,
parser_with_context!(warning_delay)(context),
))),
))(input)
} }
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
@ -506,29 +515,66 @@ fn time_range_rest_end<'b, 'g, 'r, 's>(
fn repeater<'b, 'g, 'r, 's>( fn repeater<'b, 'g, 'r, 's>(
_context: RefContext<'b, 'g, 'r, 's>, _context: RefContext<'b, 'g, 'r, 's>,
input: OrgSource<'s>, input: OrgSource<'s>,
) -> Res<OrgSource<'s>, OrgSource<'s>> { ) -> Res<OrgSource<'s>, Repeater> {
// + for cumulative type // + for cumulative type
// ++ for catch-up type // ++ for catch-up type
// .+ for restart type // .+ for restart type
let (remaining, _mark) = alt((tag("++"), tag("+"), tag(".+")))(input)?; let (remaining, repeater_type) = alt((
let (remaining, _value) = digit0(remaining)?; map(tag("++"), |_| RepeaterType::Cumulative),
map(tag("+"), |_| RepeaterType::CatchUp),
map(tag(".+"), |_| RepeaterType::Restart),
))(input)?;
let (remaining, value) = digit1(remaining)?;
let value = Into::<&str>::into(value)
.parse()
.expect("digit1 ensures this will parse as a number.");
// h = hour, d = day, w = week, m = month, y = year // h = hour, d = day, w = week, m = month, y = year
let (remaining, _unit) = recognize(one_of("hdwmy"))(remaining)?; let (remaining, unit) = alt((
let source = get_consumed(input, remaining); map(tag("h"), |_| TimeUnit::Hour),
Ok((remaining, source)) map(tag("d"), |_| TimeUnit::Day),
map(tag("w"), |_| TimeUnit::Week),
map(tag("m"), |_| TimeUnit::Month),
map(tag("y"), |_| TimeUnit::Year),
))(remaining)?;
Ok((
remaining,
Repeater {
repeater_type,
value,
unit,
},
))
} }
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn warning_delay<'b, 'g, 'r, 's>( fn warning_delay<'b, 'g, 'r, 's>(
_context: RefContext<'b, 'g, 'r, 's>, _context: RefContext<'b, 'g, 'r, 's>,
input: OrgSource<'s>, input: OrgSource<'s>,
) -> Res<OrgSource<'s>, OrgSource<'s>> { ) -> Res<OrgSource<'s>, WarningDelay> {
// - for all type // - for all type
// -- for first type // -- for first type
let (remaining, _mark) = alt((tag("--"), tag("-")))(input)?; let (remaining, warning_delay_type) = alt((
let (remaining, _value) = digit0(remaining)?; map(tag("--"), |_| WarningDelayType::First),
map(tag("-"), |_| WarningDelayType::All),
))(input)?;
let (remaining, value) = digit1(remaining)?;
let value = Into::<&str>::into(value)
.parse()
.expect("digit1 ensures this will parse as a number.");
// h = hour, d = day, w = week, m = month, y = year // h = hour, d = day, w = week, m = month, y = year
let (remaining, _unit) = recognize(one_of("hdwmy"))(remaining)?; let (remaining, unit) = alt((
let source = get_consumed(input, remaining); map(tag("h"), |_| TimeUnit::Hour),
Ok((remaining, source)) map(tag("d"), |_| TimeUnit::Day),
map(tag("w"), |_| TimeUnit::Week),
map(tag("m"), |_| TimeUnit::Month),
map(tag("y"), |_| TimeUnit::Year),
))(remaining)?;
Ok((
remaining,
WarningDelay {
warning_delay_type,
value,
unit,
},
))
} }

View File

@ -78,17 +78,23 @@ pub use object::PlainText;
pub use object::RadioLink; pub use object::RadioLink;
pub use object::RadioTarget; pub use object::RadioTarget;
pub use object::RegularLink; pub use object::RegularLink;
pub use object::Repeater;
pub use object::RepeaterType;
pub use object::RepeaterWarningDelayValueType;
pub use object::StatisticsCookie; pub use object::StatisticsCookie;
pub use object::StrikeThrough; pub use object::StrikeThrough;
pub use object::Subscript; pub use object::Subscript;
pub use object::Superscript; pub use object::Superscript;
pub use object::Target; pub use object::Target;
pub use object::Time; pub use object::Time;
pub use object::TimeUnit;
pub use object::Timestamp; pub use object::Timestamp;
pub use object::TimestampRangeType; pub use object::TimestampRangeType;
pub use object::TimestampType; pub use object::TimestampType;
pub use object::Underline; pub use object::Underline;
pub use object::Verbatim; pub use object::Verbatim;
pub use object::WarningDelay;
pub use object::WarningDelayType;
pub use object::Year; pub use object::Year;
pub use object::YearInner; pub use object::YearInner;
pub(crate) use source::SetSource; pub(crate) use source::SetSource;

View File

@ -191,6 +191,8 @@ pub struct Timestamp<'s> {
pub end: Option<Date<'s>>, pub end: Option<Date<'s>>,
pub start_time: Option<Time<'s>>, pub start_time: Option<Time<'s>>,
pub end_time: Option<Time<'s>>, pub end_time: Option<Time<'s>>,
pub repeater: Option<Repeater>,
pub warning_delay: Option<WarningDelay>,
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
@ -394,6 +396,44 @@ impl<'s> Time<'s> {
} }
} }
#[derive(Debug, PartialEq, Clone)]
pub enum RepeaterType {
Cumulative,
CatchUp,
Restart,
}
#[derive(Debug, PartialEq, Clone)]
pub enum WarningDelayType {
All,
First,
}
#[derive(Debug, PartialEq, Clone)]
pub enum TimeUnit {
Hour,
Day,
Week,
Month,
Year,
}
pub type RepeaterWarningDelayValueType = u16;
#[derive(Debug, PartialEq, Clone)]
pub struct Repeater {
pub repeater_type: RepeaterType,
pub value: RepeaterWarningDelayValueType,
pub unit: TimeUnit,
}
#[derive(Debug, PartialEq, Clone)]
pub struct WarningDelay {
pub warning_delay_type: WarningDelayType,
pub value: RepeaterWarningDelayValueType,
pub unit: TimeUnit,
}
impl<'s> GetStandardProperties<'s> for Object<'s> { impl<'s> GetStandardProperties<'s> for Object<'s> {
fn get_standard_properties<'b>(&'b self) -> &'b dyn StandardProperties<'s> { fn get_standard_properties<'b>(&'b self) -> &'b dyn StandardProperties<'s> {
match self { match self {