summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2021-08-03 15:01:05 +0200
committerGustav Sörnäs <gustav@sornas.net>2021-08-03 15:01:45 +0200
commitfc223fa9b39020306dffd93137a345af6f9b72b2 (patch)
treec440b5bf0dfd4ff1e4d56049eae31615961ec8cb
parent6496950ebd49bb3ec88c2cb5dd7a62771d57d38e (diff)
downloadmoney-fc223fa9b39020306dffd93137a345af6f9b72b2.tar.gz
parse relative date
-rw-r--r--cli/src/search.rs53
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)),