dinero/parser/tokenizers/
payee.rs1use 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 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}