summaryrefslogtreecommitdiffstats
path: root/cli/src/search.rs
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2021-08-03 14:40:03 +0200
committerGustav Sörnäs <gustav@sornas.net>2021-08-03 14:40:03 +0200
commit7f15f58224b959b7d62206580d797a71e4cbec9c (patch)
tree7b084884e5d18489e59f502f2d39d12fceab7ff6 /cli/src/search.rs
parentdc2db9dc8c89c2cf966bbc74a8d1ddfaea01c410 (diff)
downloadmoney-7f15f58224b959b7d62206580d797a71e4cbec9c.tar.gz
parse absolute dates
Diffstat (limited to 'cli/src/search.rs')
-rw-r--r--cli/src/search.rs73
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)