diff options
| author | Gustav Sörnäs <gustav@sornas.net> | 2021-08-03 14:40:03 +0200 |
|---|---|---|
| committer | Gustav Sörnäs <gustav@sornas.net> | 2021-08-03 14:40:03 +0200 |
| commit | 7f15f58224b959b7d62206580d797a71e4cbec9c (patch) | |
| tree | 7b084884e5d18489e59f502f2d39d12fceab7ff6 /cli/src/search.rs | |
| parent | dc2db9dc8c89c2cf966bbc74a8d1ddfaea01c410 (diff) | |
| download | money-7f15f58224b959b7d62206580d797a71e4cbec9c.tar.gz | |
parse absolute dates
Diffstat (limited to 'cli/src/search.rs')
| -rw-r--r-- | cli/src/search.rs | 73 |
1 files changed, 58 insertions, 15 deletions
diff --git a/cli/src/search.rs b/cli/src/search.rs index 5d2a53a..d4c107b 100644 --- a/cli/src/search.rs +++ b/cli/src/search.rs @@ -1,7 +1,7 @@ use chrono::{naive::NaiveDate, Duration}; -use nom::{branch::alt, bytes::complete::{is_not, tag}, character::complete::{alphanumeric1, char}, combinator::{map, recognize}, sequence::{delimited, preceded}}; +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 rust_decimal::Decimal; -use std::str::FromStr; +use std::{num::ParseIntError, str::FromStr}; use crate::transaction::{Category, Transaction}; @@ -15,10 +15,30 @@ 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())) + // 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_opt( + map_res( + tuple(( + take(4usize), + char('-'), + take(2usize), + char('-'), + take(2usize), + )), + |(y, _, m, _, d): (&str, _, &str, _, &str)| -> Result<_, ParseIntError> { + Ok((y.parse()?, m.parse()?, d.parse()?)) + } + ), + |(y, m, d)| NaiveDate::from_ymd_opt(y, m, d) + ), + DateIsh::Absolute + )(i) } pub fn parse_relative(s: &str) -> Option<Duration> { @@ -104,13 +124,36 @@ impl Constraint { } fn parse(i: &str) -> nom::IResult<&str, Self> { - map( - preceded( - tag("category:"), - string, + alt(( + map( + preceded( + tag("category:"), + string, + ), + |c| Constraint::Category(c.to_string()) ), - |c| Constraint::Category(c.to_string()) - )(i) + map( + preceded( + tag("before:"), + DateIsh::parse + ), + Constraint::Before + ), + map( + preceded( + tag("after:"), + DateIsh::parse + ), + Constraint::After + ), + map( + preceded( + tag("on:"), + DateIsh::parse + ), + Constraint::On + ), + ))(i) } } @@ -225,9 +268,9 @@ impl<'t> Search<'t> { let constraint = match rule.split_once(':').unwrap() { ("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)), + // ("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)), ("amount", comparison) => { let (amount, comparison) = parse_comparison(comparison).unwrap(); Constraint::AmountCompare(amount, comparison) |
