Compare warning delay and repeater.

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

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,
},
))
}