From 8143c2bf359eb833b6e456b2697e2a6945dd590f Mon Sep 17 00:00:00 2001 From: Joscha Date: Fri, 19 Nov 2021 19:49:18 +0100 Subject: [PATCH] Parse DATE with fixed start date --- src/parse.rs | 86 +++++++++++++++++++++++++++++++++++----- src/parse/todayfile.pest | 8 ++-- 2 files changed, 80 insertions(+), 14 deletions(-) diff --git a/src/parse.rs b/src/parse.rs index 24f5b25..ddeeabe 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -30,6 +30,11 @@ fn fail, T>(span: Span, message: S) -> Result { Err(error(span, message)) } +fn parse_number(p: Pair) -> Result { + assert_eq!(p.as_rule(), Rule::number); + Ok(p.as_str().parse().unwrap()) +} + fn parse_title(p: Pair) -> Result { assert_eq!(p.as_rule(), Rule::title); let p = p.into_inner().next().unwrap(); @@ -101,7 +106,7 @@ fn parse_amount(p: Pair) -> Result { assert_eq!(p.as_rule(), Rule::amount); let mut sign = None; - let mut value = 0; + let mut value = 1; for p in p.into_inner() { match p.as_rule() { Rule::amount_sign => { @@ -111,7 +116,7 @@ fn parse_amount(p: Pair) -> Result { _ => unreachable!(), }) } - Rule::amount_value => value = p.as_str().parse().unwrap(), + Rule::number => value = parse_number(p)?, _ => unreachable!(), } } @@ -188,13 +193,13 @@ fn parse_delta(p: Pair) -> Result { Rule::delta_weekdays => steps.push(parse_delta_weekdays(p, &mut sign)?), Rule::delta_minutes => steps.push(parse_delta_step(p, &mut sign, DeltaStep::Minute)?), Rule::delta_years => steps.push(parse_delta_step(p, &mut sign, DeltaStep::Year)?), - Rule::delta_months => steps.push(parse_delta_step(p, &mut sign, DeltaStep::Minute)?), + Rule::delta_months => steps.push(parse_delta_step(p, &mut sign, DeltaStep::Month)?), Rule::delta_months_reverse => { - steps.push(parse_delta_step(p, &mut sign, DeltaStep::Minute)?) + steps.push(parse_delta_step(p, &mut sign, DeltaStep::MonthReverse)?) } - Rule::delta_days => steps.push(parse_delta_step(p, &mut sign, DeltaStep::Minute)?), - Rule::delta_weeks => steps.push(parse_delta_step(p, &mut sign, DeltaStep::Minute)?), - Rule::delta_hours => steps.push(parse_delta_step(p, &mut sign, DeltaStep::Minute)?), + Rule::delta_days => steps.push(parse_delta_step(p, &mut sign, DeltaStep::Day)?), + Rule::delta_weeks => steps.push(parse_delta_step(p, &mut sign, DeltaStep::Week)?), + Rule::delta_hours => steps.push(parse_delta_step(p, &mut sign, DeltaStep::Hour)?), _ => unreachable!(), } } @@ -202,10 +207,71 @@ fn parse_delta(p: Pair) -> Result { Ok(Delta(steps)) } +fn parse_date_fixed_start(p: Pair, spec: &mut DateSpec) -> Result<()> { + assert_eq!(p.as_rule(), Rule::date_fixed_start); + + for p in p.into_inner() { + match p.as_rule() { + Rule::datum => spec.start = parse_datum(p)?, + Rule::delta => spec.start_delta = Some(parse_delta(p)?), + Rule::time => spec.start_time = Some(parse_time(p)?), + _ => unreachable!(), + } + } + + Ok(()) +} + +fn parse_date_fixed_end(p: Pair, spec: &mut DateSpec) -> Result<()> { + assert_eq!(p.as_rule(), Rule::date_fixed_end); + + for p in p.into_inner() { + match p.as_rule() { + Rule::datum => spec.end = Some(parse_datum(p)?), + Rule::delta => spec.end_delta = Some(parse_delta(p)?), + Rule::time => spec.end_time = Some(parse_time(p)?), + _ => unreachable!(), + } + } + + Ok(()) +} + +fn parse_date_fixed_repeat(p: Pair, spec: &mut DateSpec) -> Result<()> { + assert_eq!(p.as_rule(), Rule::date_fixed_repeat); + let mut p = p.into_inner(); + + if let Some(p) = p.next() { + spec.repeat = Some(parse_delta(p)?); + } + + assert_eq!(p.next(), None); + Ok(()) +} + fn parse_date_fixed(p: Pair) -> Result { assert_eq!(p.as_rule(), Rule::date_fixed); - dbg!(p); - todo!() + + let mut spec = DateSpec { + start: NaiveDate::from_ymd(0, 1, 1), + start_delta: None, + start_time: None, + end: None, + end_delta: None, + end_time: None, + repeat: None, + }; + + for p in p.into_inner() { + match p.as_rule() { + Rule::date_fixed_start => parse_date_fixed_start(p, &mut spec)?, + Rule::date_fixed_end => parse_date_fixed_end(p, &mut spec)?, + Rule::date_fixed_repeat => parse_date_fixed_repeat(p, &mut spec)?, + _ => unreachable!(), + } + } + + Ok(spec) } fn parse_date_expr(p: Pair) -> Result { @@ -348,7 +414,7 @@ fn parse_task(p: Pair) -> Result { } fn parse_note(p: Pair) -> Result { - assert_eq!(p.as_rule(), Rule::task); + assert_eq!(p.as_rule(), Rule::note); let mut p = p.into_inner(); let title = parse_title(p.next().unwrap())?; diff --git a/src/parse/todayfile.pest b/src/parse/todayfile.pest index 3075971..63b6398 100644 --- a/src/parse/todayfile.pest +++ b/src/parse/todayfile.pest @@ -3,6 +3,8 @@ WHITESPACE = _{ !eol ~ WHITE_SPACE } rest_some = { (!eol ~ ANY)+ } rest_any = { (!eol ~ ANY)* } +number = @{ ASCII_DIGIT{1,9} } // Fits into an i32 + title = { WHITESPACE ~ rest_some ~ eol } year = @{ ASCII_DIGIT{4} } @@ -17,9 +19,8 @@ time = ${ hour ~ ":" ~ minute } weekday = { "mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun" } -amount_sign = { ("+" | "-")? } -amount_value = { ASCII_DIGIT{0,9} } // Fits in an i32 -amount = { amount_sign ~ amount_value } +amount_sign = { "+" | "-" } +amount = { amount_sign? ~ number? } delta_weekdays = { amount ~ weekday } delta_minutes = { amount ~ "min" } delta_years = { amount ~ "y" } @@ -42,7 +43,6 @@ delta = { } paren_expr = { "(" ~ expr ~ ")" } -number = @{ ASCII_DIGIT{1,9} } // Fits in an i32 boolean = { "true" | "false" } variable = { "j"