Carry source spans for error messages
This commit is contained in:
parent
1d80ab681e
commit
1170009b4f
6 changed files with 132 additions and 59 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
use chrono::NaiveDate;
|
use chrono::NaiveDate;
|
||||||
|
|
||||||
use crate::files::commands::{self, DoneDate, Time};
|
use crate::files::commands::{self, DoneDate, Spanned, Time};
|
||||||
use crate::files::Source;
|
use crate::files::Source;
|
||||||
|
|
||||||
use super::delta::{Delta, DeltaStep};
|
use super::delta::{Delta, DeltaStep};
|
||||||
|
|
@ -29,7 +29,9 @@ impl From<&commands::DateSpec> for DateSpec {
|
||||||
.map(|delta| delta.into())
|
.map(|delta| delta.into())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
if let Some(time) = spec.end_time {
|
if let Some(time) = spec.end_time {
|
||||||
end_delta.steps.push(DeltaStep::Time(time));
|
end_delta
|
||||||
|
.steps
|
||||||
|
.push(Spanned::new(time.span, DeltaStep::Time(time.value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let repeat: Option<Delta> = spec.repeat.as_ref().map(|repeat| (&repeat.delta).into());
|
let repeat: Option<Delta> = spec.repeat.as_ref().map(|repeat| (&repeat.delta).into());
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
use crate::files::commands::{self, Time, Weekday};
|
use crate::files::commands::{self, Spanned, Time, Weekday};
|
||||||
|
|
||||||
/// Like [`commands::DeltaStep`] but includes a new constructor,
|
/// Like [`commands::DeltaStep`] but includes a new constructor,
|
||||||
/// [`DeltaStep::Time`].
|
/// [`DeltaStep::Time`].
|
||||||
|
|
@ -122,23 +122,27 @@ impl DeltaStep {
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Delta {
|
pub struct Delta {
|
||||||
pub steps: Vec<DeltaStep>,
|
pub steps: Vec<Spanned<DeltaStep>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&commands::Delta> for Delta {
|
impl From<&commands::Delta> for Delta {
|
||||||
fn from(delta: &commands::Delta) -> Self {
|
fn from(delta: &commands::Delta) -> Self {
|
||||||
Self {
|
Self {
|
||||||
steps: delta.0.iter().map(|&step| step.into()).collect(),
|
steps: delta
|
||||||
|
.0
|
||||||
|
.iter()
|
||||||
|
.map(|step| Spanned::new(step.span, step.value.into()))
|
||||||
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Delta {
|
impl Delta {
|
||||||
pub fn lower_bound(&self) -> i32 {
|
pub fn lower_bound(&self) -> i32 {
|
||||||
self.steps.iter().map(DeltaStep::lower_bound).sum()
|
self.steps.iter().map(|step| step.value.lower_bound()).sum()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn upper_bound(&self) -> i32 {
|
pub fn upper_bound(&self) -> i32 {
|
||||||
self.steps.iter().map(DeltaStep::upper_bound).sum()
|
self.steps.iter().map(|step| step.value.upper_bound()).sum()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::files::commands::{self, DoneDate, Expr, Time, Var};
|
use crate::files::commands::{self, DoneDate, Expr, Spanned, Time, Var};
|
||||||
use crate::files::Source;
|
use crate::files::Source;
|
||||||
|
|
||||||
use super::delta::{Delta, DeltaStep};
|
use super::delta::{Delta, DeltaStep};
|
||||||
|
|
@ -28,7 +28,9 @@ impl From<&commands::FormulaSpec> for FormulaSpec {
|
||||||
.map(|delta| delta.into())
|
.map(|delta| delta.into())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
if let Some(time) = spec.end_time {
|
if let Some(time) = spec.end_time {
|
||||||
end_delta.steps.push(DeltaStep::Time(time));
|
end_delta
|
||||||
|
.steps
|
||||||
|
.push(Spanned::new(time.span, DeltaStep::Time(time.value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -49,15 +51,21 @@ impl From<&commands::WeekdaySpec> for FormulaSpec {
|
||||||
|
|
||||||
let mut end_delta = Delta::default();
|
let mut end_delta = Delta::default();
|
||||||
if let Some(wd) = spec.end {
|
if let Some(wd) = spec.end {
|
||||||
end_delta.steps.push(DeltaStep::Weekday(1, wd));
|
end_delta
|
||||||
|
.steps
|
||||||
|
.push(Spanned::new(wd.span, DeltaStep::Weekday(1, wd.value)));
|
||||||
}
|
}
|
||||||
if let Some(delta) = &spec.end_delta {
|
if let Some(delta) = &spec.end_delta {
|
||||||
for step in &delta.0 {
|
for step in &delta.0 {
|
||||||
end_delta.steps.push((*step).into());
|
end_delta
|
||||||
|
.steps
|
||||||
|
.push(Spanned::new(step.span, step.value.into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(time) = spec.end_time {
|
if let Some(time) = spec.end_time {
|
||||||
end_delta.steps.push(DeltaStep::Time(time));
|
end_delta
|
||||||
|
.steps
|
||||||
|
.push(Spanned::new(time.span, DeltaStep::Time(time.value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,48 @@
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
use chrono::NaiveDate;
|
use chrono::NaiveDate;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct Span {
|
||||||
|
pub start: usize,
|
||||||
|
pub end: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&pest::Span<'a>> for Span {
|
||||||
|
fn from(pspan: &pest::Span<'a>) -> Self {
|
||||||
|
Self {
|
||||||
|
start: pspan.start(),
|
||||||
|
end: pspan.end(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct Spanned<T> {
|
||||||
|
pub span: Span,
|
||||||
|
pub value: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: fmt::Debug> fmt::Debug for Spanned<T> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||||
|
self.value.fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Spanned<T> {
|
||||||
|
pub fn new(span: Span, value: T) -> Self {
|
||||||
|
Self { span, value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// I don't know how one would write this. It works as a polymorphic standalone
|
||||||
|
// function, but not in an impl block.
|
||||||
|
// impl<S, T: Into<S>> Spanned<T> {
|
||||||
|
// pub fn convert(&self) -> Spanned<S> {
|
||||||
|
// Self::new(self.span, self.value.into())
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct Time {
|
pub struct Time {
|
||||||
pub hour: u8,
|
pub hour: u8,
|
||||||
|
|
@ -95,7 +138,7 @@ impl DeltaStep {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Delta(pub Vec<DeltaStep>);
|
pub struct Delta(pub Vec<Spanned<DeltaStep>>);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Repeat {
|
pub struct Repeat {
|
||||||
|
|
@ -110,9 +153,9 @@ pub struct DateSpec {
|
||||||
pub start: NaiveDate,
|
pub start: NaiveDate,
|
||||||
pub start_delta: Option<Delta>,
|
pub start_delta: Option<Delta>,
|
||||||
pub start_time: Option<Time>,
|
pub start_time: Option<Time>,
|
||||||
pub end: Option<NaiveDate>,
|
pub end: Option<Spanned<NaiveDate>>,
|
||||||
pub end_delta: Option<Delta>,
|
pub end_delta: Option<Delta>,
|
||||||
pub end_time: Option<Time>,
|
pub end_time: Option<Spanned<Time>>,
|
||||||
pub repeat: Option<Repeat>,
|
pub repeat: Option<Repeat>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -120,9 +163,9 @@ pub struct DateSpec {
|
||||||
pub struct WeekdaySpec {
|
pub struct WeekdaySpec {
|
||||||
pub start: Weekday,
|
pub start: Weekday,
|
||||||
pub start_time: Option<Time>,
|
pub start_time: Option<Time>,
|
||||||
pub end: Option<Weekday>,
|
pub end: Option<Spanned<Weekday>>,
|
||||||
pub end_delta: Option<Delta>,
|
pub end_delta: Option<Delta>,
|
||||||
pub end_time: Option<Time>,
|
pub end_time: Option<Spanned<Time>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
|
@ -289,7 +332,7 @@ pub struct FormulaSpec {
|
||||||
pub start_delta: Option<Delta>,
|
pub start_delta: Option<Delta>,
|
||||||
pub start_time: Option<Time>,
|
pub start_time: Option<Time>,
|
||||||
pub end_delta: Option<Delta>,
|
pub end_delta: Option<Delta>,
|
||||||
pub end_time: Option<Time>,
|
pub end_time: Option<Spanned<Time>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -368,6 +411,7 @@ pub struct BirthdaySpec {
|
||||||
pub struct Birthday {
|
pub struct Birthday {
|
||||||
pub title: String,
|
pub title: String,
|
||||||
pub when: BirthdaySpec,
|
pub when: BirthdaySpec,
|
||||||
|
// pub until: Option<NaiveDate>, // TODO Add UNTIL to birthday
|
||||||
pub desc: Vec<String>,
|
pub desc: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,15 @@ use chrono::Datelike;
|
||||||
|
|
||||||
use super::commands::{
|
use super::commands::{
|
||||||
Birthday, BirthdaySpec, Command, DateSpec, Delta, DeltaStep, Done, DoneDate, Expr, File,
|
Birthday, BirthdaySpec, Command, DateSpec, Delta, DeltaStep, Done, DoneDate, Expr, File,
|
||||||
FormulaSpec, Note, Repeat, Spec, Task, Time, Var, Weekday, WeekdaySpec,
|
FormulaSpec, Note, Repeat, Spanned, Spec, Task, Time, Var, Weekday, WeekdaySpec,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
impl<T: fmt::Display> fmt::Display for Spanned<T> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
self.value.fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn format_desc(f: &mut fmt::Formatter<'_>, desc: &[String]) -> fmt::Result {
|
fn format_desc(f: &mut fmt::Formatter<'_>, desc: &[String]) -> fmt::Result {
|
||||||
for line in desc {
|
for line in desc {
|
||||||
if line.is_empty() {
|
if line.is_empty() {
|
||||||
|
|
@ -46,7 +52,7 @@ impl fmt::Display for Delta {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let mut sign = 0;
|
let mut sign = 0;
|
||||||
for step in &self.0 {
|
for step in &self.0 {
|
||||||
format_delta_step(f, step, &mut sign)?;
|
format_delta_step(f, &step.value, &mut sign)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use pest::iterators::Pair;
|
||||||
use pest::prec_climber::{Assoc, Operator, PrecClimber};
|
use pest::prec_climber::{Assoc, Operator, PrecClimber};
|
||||||
use pest::{Parser, Span};
|
use pest::{Parser, Span};
|
||||||
|
|
||||||
use crate::files::commands::Repeat;
|
use crate::files::commands::{Repeat, Spanned};
|
||||||
|
|
||||||
use super::commands::{
|
use super::commands::{
|
||||||
Birthday, BirthdaySpec, Command, DateSpec, Delta, DeltaStep, Done, DoneDate, Expr, File,
|
Birthday, BirthdaySpec, Command, DateSpec, Delta, DeltaStep, Done, DoneDate, Expr, File,
|
||||||
|
|
@ -56,9 +56,10 @@ fn parse_title(p: Pair<'_, Rule>) -> String {
|
||||||
p.as_str().trim().to_string()
|
p.as_str().trim().to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_datum(p: Pair<'_, Rule>) -> Result<NaiveDate> {
|
fn parse_datum(p: Pair<'_, Rule>) -> Result<Spanned<NaiveDate>> {
|
||||||
assert_eq!(p.as_rule(), Rule::datum);
|
assert_eq!(p.as_rule(), Rule::datum);
|
||||||
let span = p.as_span();
|
let pspan = p.as_span();
|
||||||
|
let span = (&pspan).into();
|
||||||
let mut p = p.into_inner();
|
let mut p = p.into_inner();
|
||||||
|
|
||||||
let year = p.next().unwrap().as_str().parse().unwrap();
|
let year = p.next().unwrap().as_str().parse().unwrap();
|
||||||
|
|
@ -68,14 +69,15 @@ fn parse_datum(p: Pair<'_, Rule>) -> Result<NaiveDate> {
|
||||||
assert_eq!(p.next(), None);
|
assert_eq!(p.next(), None);
|
||||||
|
|
||||||
match NaiveDate::from_ymd_opt(year, month, day) {
|
match NaiveDate::from_ymd_opt(year, month, day) {
|
||||||
Some(date) => Ok(date),
|
Some(date) => Ok(Spanned::new(span, date)),
|
||||||
None => fail(span, "invalid date"),
|
None => fail(pspan, "invalid date"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_time(p: Pair<'_, Rule>) -> Result<Time> {
|
fn parse_time(p: Pair<'_, Rule>) -> Result<Spanned<Time>> {
|
||||||
assert_eq!(p.as_rule(), Rule::time);
|
assert_eq!(p.as_rule(), Rule::time);
|
||||||
let span = p.as_span();
|
let pspan = p.as_span();
|
||||||
|
let span = (&pspan).into();
|
||||||
let mut p = p.into_inner();
|
let mut p = p.into_inner();
|
||||||
|
|
||||||
let hour = p.next().unwrap().as_str().parse().unwrap();
|
let hour = p.next().unwrap().as_str().parse().unwrap();
|
||||||
|
|
@ -84,8 +86,8 @@ fn parse_time(p: Pair<'_, Rule>) -> Result<Time> {
|
||||||
assert_eq!(p.next(), None);
|
assert_eq!(p.next(), None);
|
||||||
|
|
||||||
match Time::new(hour, min) {
|
match Time::new(hour, min) {
|
||||||
Some(time) => Ok(time),
|
Some(time) => Ok(Spanned::new(span, time)),
|
||||||
None => fail(span, "invalid time"),
|
None => fail(pspan, "invalid time"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -138,9 +140,10 @@ fn parse_amount(p: Pair<'_, Rule>) -> Amount {
|
||||||
Amount { sign, value }
|
Amount { sign, value }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_weekday(p: Pair<'_, Rule>) -> Weekday {
|
fn parse_weekday(p: Pair<'_, Rule>) -> Spanned<Weekday> {
|
||||||
assert_eq!(p.as_rule(), Rule::weekday);
|
assert_eq!(p.as_rule(), Rule::weekday);
|
||||||
match p.as_str() {
|
let span = (&p.as_span()).into();
|
||||||
|
let wd = match p.as_str() {
|
||||||
"mon" => Weekday::Monday,
|
"mon" => Weekday::Monday,
|
||||||
"tue" => Weekday::Tuesday,
|
"tue" => Weekday::Tuesday,
|
||||||
"wed" => Weekday::Wednesday,
|
"wed" => Weekday::Wednesday,
|
||||||
|
|
@ -149,32 +152,34 @@ fn parse_weekday(p: Pair<'_, Rule>) -> Weekday {
|
||||||
"sat" => Weekday::Saturday,
|
"sat" => Weekday::Saturday,
|
||||||
"sun" => Weekday::Sunday,
|
"sun" => Weekday::Sunday,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
};
|
||||||
|
Spanned::new(span, wd)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_delta_weekdays(p: Pair<'_, Rule>, sign: &mut Option<Sign>) -> Result<DeltaStep> {
|
fn parse_delta_weekdays(p: Pair<'_, Rule>, sign: &mut Option<Sign>) -> Result<Spanned<DeltaStep>> {
|
||||||
assert_eq!(p.as_rule(), Rule::delta_weekdays);
|
assert_eq!(p.as_rule(), Rule::delta_weekdays);
|
||||||
let span = p.as_span();
|
let pspan = p.as_span();
|
||||||
|
let span = (&pspan).into();
|
||||||
let mut p = p.into_inner();
|
let mut p = p.into_inner();
|
||||||
|
|
||||||
let amount = parse_amount(p.next().unwrap()).with_prev_sign(*sign);
|
let amount = parse_amount(p.next().unwrap()).with_prev_sign(*sign);
|
||||||
let weekday = parse_weekday(p.next().unwrap());
|
let weekday = parse_weekday(p.next().unwrap()).value;
|
||||||
|
|
||||||
assert_eq!(p.next(), None);
|
assert_eq!(p.next(), None);
|
||||||
|
|
||||||
let value = amount
|
let value = amount
|
||||||
.value()
|
.value()
|
||||||
.ok_or_else(|| error(span, "ambiguous sign"))?;
|
.ok_or_else(|| error(pspan, "ambiguous sign"))?;
|
||||||
*sign = amount.sign;
|
*sign = amount.sign;
|
||||||
|
|
||||||
Ok(DeltaStep::Weekday(value, weekday))
|
Ok(Spanned::new(span, DeltaStep::Weekday(value, weekday)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_delta_step(
|
fn parse_delta_step(
|
||||||
p: Pair<'_, Rule>,
|
p: Pair<'_, Rule>,
|
||||||
sign: &mut Option<Sign>,
|
sign: &mut Option<Sign>,
|
||||||
f: impl FnOnce(i32) -> DeltaStep,
|
f: impl FnOnce(i32) -> DeltaStep,
|
||||||
) -> Result<DeltaStep> {
|
) -> Result<Spanned<DeltaStep>> {
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
p.as_rule(),
|
p.as_rule(),
|
||||||
Rule::delta_years
|
Rule::delta_years
|
||||||
|
|
@ -186,14 +191,15 @@ fn parse_delta_step(
|
||||||
| Rule::delta_minutes
|
| Rule::delta_minutes
|
||||||
));
|
));
|
||||||
|
|
||||||
let span = p.as_span();
|
let pspan = p.as_span();
|
||||||
|
let span = (&pspan).into();
|
||||||
let amount = parse_amount(p.into_inner().next().unwrap()).with_prev_sign(*sign);
|
let amount = parse_amount(p.into_inner().next().unwrap()).with_prev_sign(*sign);
|
||||||
let value = amount
|
let value = amount
|
||||||
.value()
|
.value()
|
||||||
.ok_or_else(|| error(span, "ambiguous sign"))?;
|
.ok_or_else(|| error(pspan, "ambiguous sign"))?;
|
||||||
|
|
||||||
*sign = amount.sign;
|
*sign = amount.sign;
|
||||||
Ok(f(value))
|
Ok(Spanned::new(span, f(value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_delta(p: Pair<'_, Rule>) -> Result<Delta> {
|
fn parse_delta(p: Pair<'_, Rule>) -> Result<Delta> {
|
||||||
|
|
@ -226,9 +232,9 @@ fn parse_date_fixed_start(p: Pair<'_, Rule>, spec: &mut DateSpec) -> Result<()>
|
||||||
|
|
||||||
for p in p.into_inner() {
|
for p in p.into_inner() {
|
||||||
match p.as_rule() {
|
match p.as_rule() {
|
||||||
Rule::datum => spec.start = parse_datum(p)?,
|
Rule::datum => spec.start = parse_datum(p)?.value,
|
||||||
Rule::delta => spec.start_delta = Some(parse_delta(p)?),
|
Rule::delta => spec.start_delta = Some(parse_delta(p)?),
|
||||||
Rule::time => spec.start_time = Some(parse_time(p)?),
|
Rule::time => spec.start_time = Some(parse_time(p)?.value),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -431,7 +437,7 @@ fn parse_date_expr_start(p: Pair<'_, Rule>, spec: &mut FormulaSpec) -> Result<()
|
||||||
match p.as_rule() {
|
match p.as_rule() {
|
||||||
Rule::paren_expr => spec.start = Some(parse_expr(p.into_inner().next().unwrap())),
|
Rule::paren_expr => spec.start = Some(parse_expr(p.into_inner().next().unwrap())),
|
||||||
Rule::delta => spec.start_delta = Some(parse_delta(p)?),
|
Rule::delta => spec.start_delta = Some(parse_delta(p)?),
|
||||||
Rule::time => spec.start_time = Some(parse_time(p)?),
|
Rule::time => spec.start_time = Some(parse_time(p)?.value),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -480,8 +486,8 @@ fn parse_date_weekday_start(p: Pair<'_, Rule>, spec: &mut WeekdaySpec) -> Result
|
||||||
|
|
||||||
for p in p.into_inner() {
|
for p in p.into_inner() {
|
||||||
match p.as_rule() {
|
match p.as_rule() {
|
||||||
Rule::weekday => spec.start = parse_weekday(p),
|
Rule::weekday => spec.start = parse_weekday(p).value,
|
||||||
Rule::time => spec.start_time = Some(parse_time(p)?),
|
Rule::time => spec.start_time = Some(parse_time(p)?.value),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -539,17 +545,20 @@ fn parse_date(p: Pair<'_, Rule>) -> Result<Spec> {
|
||||||
|
|
||||||
fn parse_from(p: Pair<'_, Rule>) -> Result<NaiveDate> {
|
fn parse_from(p: Pair<'_, Rule>) -> Result<NaiveDate> {
|
||||||
assert_eq!(p.as_rule(), Rule::from);
|
assert_eq!(p.as_rule(), Rule::from);
|
||||||
parse_datum(p.into_inner().next().unwrap())
|
let datum = parse_datum(p.into_inner().next().unwrap())?;
|
||||||
|
Ok(datum.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_until(p: Pair<'_, Rule>) -> Result<NaiveDate> {
|
fn parse_until(p: Pair<'_, Rule>) -> Result<NaiveDate> {
|
||||||
assert_eq!(p.as_rule(), Rule::until);
|
assert_eq!(p.as_rule(), Rule::until);
|
||||||
parse_datum(p.into_inner().next().unwrap())
|
let datum = parse_datum(p.into_inner().next().unwrap())?;
|
||||||
|
Ok(datum.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_except(p: Pair<'_, Rule>) -> Result<NaiveDate> {
|
fn parse_except(p: Pair<'_, Rule>) -> Result<NaiveDate> {
|
||||||
assert_eq!(p.as_rule(), Rule::except);
|
assert_eq!(p.as_rule(), Rule::except);
|
||||||
parse_datum(p.into_inner().next().unwrap())
|
let datum = parse_datum(p.into_inner().next().unwrap())?;
|
||||||
|
Ok(datum.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_donedate(p: Pair<'_, Rule>) -> Result<DoneDate> {
|
fn parse_donedate(p: Pair<'_, Rule>) -> Result<DoneDate> {
|
||||||
|
|
@ -561,24 +570,24 @@ fn parse_donedate(p: Pair<'_, Rule>) -> Result<DoneDate> {
|
||||||
// the list ;-;
|
// the list ;-;
|
||||||
Ok(match ps.len() {
|
Ok(match ps.len() {
|
||||||
1 => DoneDate::Date {
|
1 => DoneDate::Date {
|
||||||
root: parse_datum(ps.pop().unwrap())?,
|
root: parse_datum(ps.pop().unwrap())?.value,
|
||||||
},
|
},
|
||||||
2 => match ps[1].as_rule() {
|
2 => match ps[1].as_rule() {
|
||||||
Rule::time => DoneDate::DateWithTime {
|
Rule::time => DoneDate::DateWithTime {
|
||||||
root_time: parse_time(ps.pop().unwrap())?,
|
root_time: parse_time(ps.pop().unwrap())?.value,
|
||||||
root: parse_datum(ps.pop().unwrap())?,
|
root: parse_datum(ps.pop().unwrap())?.value,
|
||||||
},
|
},
|
||||||
Rule::datum => DoneDate::DateToDate {
|
Rule::datum => DoneDate::DateToDate {
|
||||||
other: parse_datum(ps.pop().unwrap())?,
|
other: parse_datum(ps.pop().unwrap())?.value,
|
||||||
root: parse_datum(ps.pop().unwrap())?,
|
root: parse_datum(ps.pop().unwrap())?.value,
|
||||||
},
|
},
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
4 => DoneDate::DateToDateWithTime {
|
4 => DoneDate::DateToDateWithTime {
|
||||||
other_time: parse_time(ps.pop().unwrap())?,
|
other_time: parse_time(ps.pop().unwrap())?.value,
|
||||||
other: parse_datum(ps.pop().unwrap())?,
|
other: parse_datum(ps.pop().unwrap())?.value,
|
||||||
root_time: parse_time(ps.pop().unwrap())?,
|
root_time: parse_time(ps.pop().unwrap())?.value,
|
||||||
root: parse_datum(ps.pop().unwrap())?,
|
root: parse_datum(ps.pop().unwrap())?.value,
|
||||||
},
|
},
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
})
|
})
|
||||||
|
|
@ -588,7 +597,7 @@ fn parse_done(p: Pair<'_, Rule>) -> Result<Done> {
|
||||||
assert_eq!(p.as_rule(), Rule::done);
|
assert_eq!(p.as_rule(), Rule::done);
|
||||||
let mut p = p.into_inner();
|
let mut p = p.into_inner();
|
||||||
|
|
||||||
let done_at = parse_datum(p.next().unwrap())?;
|
let done_at = parse_datum(p.next().unwrap())?.value;
|
||||||
let date = if let Some(p) = p.next() {
|
let date = if let Some(p) = p.next() {
|
||||||
Some(parse_donedate(p)?)
|
Some(parse_donedate(p)?)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue