diff options
| author | Gustav Sörnäs <gustav@sornas.net> | 2021-08-03 15:01:05 +0200 |
|---|---|---|
| committer | Gustav Sörnäs <gustav@sornas.net> | 2021-08-03 15:01:45 +0200 |
| commit | fc223fa9b39020306dffd93137a345af6f9b72b2 (patch) | |
| tree | c440b5bf0dfd4ff1e4d56049eae31615961ec8cb | |
| parent | 6496950ebd49bb3ec88c2cb5dd7a62771d57d38e (diff) | |
| download | money-fc223fa9b39020306dffd93137a345af6f9b72b2.tar.gz | |
parse relative date
| -rw-r--r-- | cli/src/search.rs | 53 |
1 files changed, 31 insertions, 22 deletions
diff --git a/cli/src/search.rs b/cli/src/search.rs index 50ab32a..eaf1d06 100644 --- a/cli/src/search.rs +++ b/cli/src/search.rs @@ -1,7 +1,11 @@ use chrono::{naive::NaiveDate, Duration}; -use nom::{branch::alt, bytes::complete::{is_not, tag, take}, character::complete::{alphanumeric1, char}, combinator::{map, map_opt, map_res, recognize}, sequence::{delimited, preceded, tuple}}; +use nom::branch::alt; +use nom::bytes::complete::{is_not, tag, take}; +use nom::character::complete::{alphanumeric1, anychar, char, digit1}; +use nom::combinator::{map, map_res, recognize}; +use nom::sequence::{delimited, pair, preceded}; use rust_decimal::Decimal; -use std::{num::ParseIntError, str::FromStr}; +use std::str::FromStr; use crate::transaction::{Category, Transaction}; @@ -15,29 +19,34 @@ pub enum DateIsh { } impl DateIsh { - // pub fn parse(s: &str) -> Self { - // NaiveDate::parse_from_str(s, "%Y-%m-%d") - // .map(DateIsh::Absolute) - // .unwrap_or_else(|_| DateIsh::Relative(Self::parse_relative(s).unwrap())) - // } fn parse(i: &str) -> nom::IResult<&str, Self> { - map( - map_res( - take(10usize), - |s| NaiveDate::parse_from_str(s, "%Y-%m-%d"), + alt(( + map( + map_res( + take(10usize), + |s| NaiveDate::parse_from_str(s, "%Y-%m-%d"), + ), + DateIsh::Absolute ), - DateIsh::Absolute - )(i) + map( + Self::parse_relative, + DateIsh::Relative + ) + ))(i) } - pub fn parse_relative(s: &str) -> Option<Duration> { - //TODO Month and year. Would depend on current date so maybe parse in one place. - let num = s[..s.len()-1].parse().ok()?; - Some(match s.chars().last()? { - 'd' => Duration::days(num), - 'w' => Duration::weeks(num), - _ => unimplemented!(), - }) + fn parse_relative(i: &str) -> nom::IResult<&str, Duration> { + map( + pair( + digit1, + anychar + ), + |(amount, unit): (&str, char)| match unit { + 'd' => Duration::days(amount.parse().unwrap()), + 'w' => Duration::days(amount.parse().unwrap()), + _ => unimplemented!(), + } + )(i) } pub fn get(self) -> NaiveDate { @@ -256,7 +265,7 @@ impl<'t> Search<'t> { //TODO category:"foo bar" let constraint = match rule.split_once(':').unwrap() { - ("category", category) => Constraint::Category(category.to_string()), + // ("category", category) => Constraint::Category(category.to_string()), // ("before", date_ish) => Constraint::Before(DateIsh::parse(date_ish)), // ("after", date_ish) => Constraint::After(DateIsh::parse(date_ish)), // ("on", date_ish) => Constraint::On(DateIsh::parse(date_ish)), |
