dinero/parser/tokenizers/
payee.rs

1use std::collections::HashSet;
2
3use regex::Regex;
4
5use crate::models::{Origin, Payee};
6use crate::parser::Tokenizer;
7
8use super::super::Rule;
9
10use crate::parser::utils::parse_string;
11
12use pest::iterators::Pair;
13
14impl<'a> Tokenizer<'a> {
15    pub(crate) fn parse_payee(&self, element: Pair<Rule>) -> Payee {
16        let mut parsed = element.into_inner();
17        let name = parse_string(parsed.next().unwrap());
18        let mut note: Option<String> = None;
19        let mut alias = HashSet::new();
20
21        for part in parsed {
22            match part.as_rule() {
23                Rule::comment => {}
24                Rule::payee_property => {
25                    let mut property = part.into_inner();
26                    match property.next().unwrap().as_rule() {
27                        Rule::alias => {
28                            alias.insert(parse_string(property.next().unwrap()));
29                        }
30                        Rule::note => note = Some(parse_string(property.next().unwrap())),
31                        _ => {}
32                    }
33                }
34                _ => {}
35            }
36        }
37
38        let alias_regex: Vec<Regex> = alias
39            .iter()
40            .map(|x| Regex::new(x.clone().as_str()).unwrap())
41            .collect();
42        Payee::new(name, note, alias, alias_regex, Origin::FromDirective)
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use structopt::StructOpt;
49
50    use super::*;
51    use crate::{models::HasName, CommonOpts};
52
53    #[test]
54    //#[should_panic(expected = "Can't compare different currencies. € and USD.")]
55    fn parse_ko() {
56        let input = "payee ACME  ; From the Looney Tunes\n\tWrong Acme, Inc.\n".to_string();
57        let mut tokenizer = Tokenizer::from(input);
58        let items = tokenizer.tokenize(&CommonOpts::from_iter(["", "-f", ""].iter()));
59        assert_eq!(items.payees.len(), 0);
60    }
61
62    #[test]
63    fn parse_ok() {
64        let input = "payee ACME\n\talias Acme, Inc.\n".to_string();
65        let mut tokenizer = Tokenizer::from(input);
66
67        let items = tokenizer.tokenize(&CommonOpts::from_iter(["", "-f", ""].iter()));
68        assert_eq!(items.payees.len(), 1);
69
70        assert!(items.payees.get("acme, inc.").is_ok());
71        let payee = &items.payees.get("acme").unwrap();
72        assert_eq!(payee.get_name(), "ACME");
73    }
74}