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::RadioTarget;
use crate::types::RegularLink;
use crate::types::RepeaterType;
use crate::types::RepeaterWarningDelayValueType;
use crate::types::Section;
use crate::types::SrcBlock;
use crate::types::StandardProperties;
@ -84,6 +86,7 @@ use crate::types::TableCell;
use crate::types::TableRow;
use crate::types::Target;
use crate::types::Time;
use crate::types::TimeUnit;
use crate::types::Timestamp;
use crate::types::TimestampRangeType;
use crate::types::TimestampType;
@ -91,6 +94,7 @@ use crate::types::TodoKeywordType;
use crate::types::Underline;
use crate::types::Verbatim;
use crate::types::VerseBlock;
use crate::types::WarningDelayType;
use crate::types::Year;
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
//
// :type unquoted atom either diary, active, inactive, active-range, or inactive-range.
// :range-type unquoted atom either nil, daterange
// :raw-value quoted string of the source
// :*-start :*-end unquoted integers
// :repeater-type optional unquoted atom with value cumulate
// :repeater-value unquoted integer
// :repeater-unit unquoted atom with value week
// :warning-type optional unquoted atom with value all
// :warning-value unquoted integer
// :warning-unit unquoted atom with value day
// Compare repeater
let repeater_type = get_property_unquoted_atom(emacs, ":repeater-type")?;
let repeater_value: Option<RepeaterWarningDelayValueType> =
get_property_numeric(emacs, ":repeater-value")?;
let repeater_unit = get_property_unquoted_atom(emacs, ":repeater-unit")?;
let rust_repeater_type = rust
.repeater
.as_ref()
.map(|repeater| &repeater.repeater_type);
let rust_repeater_value = rust.repeater.as_ref().map(|repeater| repeater.value);
let rust_repeater_unit = rust.repeater.as_ref().map(|repeater| &repeater.unit);
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 {
status: this_status,

View File

@ -1,10 +1,10 @@
use nom::branch::alt;
use nom::bytes::complete::tag;
use nom::character::complete::anychar;
use nom::character::complete::digit0;
use nom::character::complete::digit1;
use nom::character::complete::one_of;
use nom::character::complete::space1;
use nom::combinator::map;
use nom::combinator::opt;
use nom::combinator::recognize;
use nom::combinator::verify;
@ -26,10 +26,15 @@ use crate::types::DayOfMonth;
use crate::types::Hour;
use crate::types::Minute;
use crate::types::Month;
use crate::types::Repeater;
use crate::types::RepeaterType;
use crate::types::Time;
use crate::types::TimeUnit;
use crate::types::Timestamp;
use crate::types::TimestampRangeType;
use crate::types::TimestampType;
use crate::types::WarningDelay;
use crate::types::WarningDelayType;
use crate::types::Year;
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
@ -70,8 +75,10 @@ fn diary_timestamp<'b, 'g, 'r, 's>(
range_type: TimestampRangeType::None,
start: None,
end: None,
start_time: None, // TODO
end_time: None, // TODO
start_time: None,
end_time: None,
repeater: None,
warning_delay: None,
},
))
}
@ -122,9 +129,9 @@ fn active_timestamp<'b, 'g, 'r, 's>(
space1,
parser_with_context!(time(true))(&time_context),
)))(remaining)?;
let (remaining, _repeater) =
let (remaining, repeater) =
opt(tuple((space1, parser_with_context!(repeater)(context))))(remaining)?;
let (remaining, _warning_delay) = opt(tuple((
let (remaining, warning_delay) = opt(tuple((
space1,
parser_with_context!(warning_delay)(context),
)))(remaining)?;
@ -144,6 +151,8 @@ fn active_timestamp<'b, 'g, 'r, 's>(
end: Some(start),
start_time: time.as_ref().map(|(_, time)| time.clone()),
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,
parser_with_context!(time(true))(&time_context),
)))(remaining)?;
let (remaining, _repeater) =
let (remaining, repeater) =
opt(tuple((space1, parser_with_context!(repeater)(context))))(remaining)?;
let (remaining, _warning_delay) = opt(tuple((
let (remaining, warning_delay) = opt(tuple((
space1,
parser_with_context!(warning_delay)(context),
)))(remaining)?;
@ -186,6 +195,8 @@ fn inactive_timestamp<'b, 'g, 'r, 's>(
end: Some(start),
start_time: time.as_ref().map(|(_, time)| time.clone()),
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,
start_time: first_timestamp.start_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)?;
let (remaining, _) = tag("-")(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)?;
let (remaining, _warning_delay) = opt(tuple((
let (remaining, warning_delay) = opt(tuple((
space1,
parser_with_context!(warning_delay)(context),
)))(remaining)?;
@ -263,6 +278,8 @@ fn active_time_range_timestamp<'b, 'g, 'r, 's>(
end: Some(start_date),
start_time: Some(first_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,
start_time: first_timestamp.start_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)?;
let (remaining, _) = tag("-")(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)?;
let (remaining, _warning_delay) = opt(tuple((
let (remaining, warning_delay) = opt(tuple((
space1,
parser_with_context!(warning_delay)(context),
)))(remaining)?;
@ -341,6 +362,8 @@ fn inactive_time_range_timestamp<'b, 'g, 'r, 's>(
end: Some(start_date),
start_time: Some(first_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"))]
fn active_time_rest_end<'b, 'g, 'r, 's>(
context: RefContext<'b, 'g, 'r, 's>,
_context: RefContext<'b, 'g, 'r, 's>,
input: OrgSource<'s>,
) -> Res<OrgSource<'s>, OrgSource<'s>> {
alt((
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)
recognize(verify(anychar, |c| ">\n".contains(*c)))(input)
}
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn inactive_time_rest_end<'b, 'g, 'r, 's>(
context: RefContext<'b, 'g, 'r, 's>,
_context: RefContext<'b, 'g, 'r, 's>,
input: OrgSource<'s>,
) -> Res<OrgSource<'s>, OrgSource<'s>> {
alt((
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)
recognize(verify(anychar, |c| "]\n".contains(*c)))(input)
}
#[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>(
_context: RefContext<'b, 'g, 'r, 's>,
input: OrgSource<'s>,
) -> Res<OrgSource<'s>, OrgSource<'s>> {
) -> Res<OrgSource<'s>, Repeater> {
// + for cumulative type
// ++ for catch-up type
// .+ for restart type
let (remaining, _mark) = alt((tag("++"), tag("+"), tag(".+")))(input)?;
let (remaining, _value) = digit0(remaining)?;
let (remaining, repeater_type) = alt((
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
let (remaining, _unit) = recognize(one_of("hdwmy"))(remaining)?;
let source = get_consumed(input, remaining);
Ok((remaining, source))
let (remaining, unit) = alt((
map(tag("h"), |_| TimeUnit::Hour),
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"))]
fn warning_delay<'b, 'g, 'r, 's>(
_context: RefContext<'b, 'g, 'r, 's>,
input: OrgSource<'s>,
) -> Res<OrgSource<'s>, OrgSource<'s>> {
) -> Res<OrgSource<'s>, WarningDelay> {
// - for all type
// -- for first type
let (remaining, _mark) = alt((tag("--"), tag("-")))(input)?;
let (remaining, _value) = digit0(remaining)?;
let (remaining, warning_delay_type) = alt((
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
let (remaining, _unit) = recognize(one_of("hdwmy"))(remaining)?;
let source = get_consumed(input, remaining);
Ok((remaining, source))
let (remaining, unit) = alt((
map(tag("h"), |_| TimeUnit::Hour),
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::RadioTarget;
pub use object::RegularLink;
pub use object::Repeater;
pub use object::RepeaterType;
pub use object::RepeaterWarningDelayValueType;
pub use object::StatisticsCookie;
pub use object::StrikeThrough;
pub use object::Subscript;
pub use object::Superscript;
pub use object::Target;
pub use object::Time;
pub use object::TimeUnit;
pub use object::Timestamp;
pub use object::TimestampRangeType;
pub use object::TimestampType;
pub use object::Underline;
pub use object::Verbatim;
pub use object::WarningDelay;
pub use object::WarningDelayType;
pub use object::Year;
pub use object::YearInner;
pub(crate) use source::SetSource;

View File

@ -191,6 +191,8 @@ pub struct Timestamp<'s> {
pub end: Option<Date<'s>>,
pub start_time: Option<Time<'s>>,
pub end_time: Option<Time<'s>>,
pub repeater: Option<Repeater>,
pub warning_delay: Option<WarningDelay>,
}
#[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> {
fn get_standard_properties<'b>(&'b self) -> &'b dyn StandardProperties<'s> {
match self {