1use crate::models::{FromDirective, HasAliases, HasName, Origin};
2use regex::Regex;
3use std::cell::RefCell;
4use std::collections::hash_map::RandomState;
5use std::collections::{HashMap, HashSet};
6use std::fmt;
7use std::fmt::{Display, Formatter};
8use std::hash::{Hash, Hasher};
9
10#[derive(Debug, Clone)]
11pub struct Payee {
12    name: String,
13    note: Option<String>,
14    alias: HashSet<String>,
15    alias_regex: Vec<Regex>,
16    origin: Origin,
17    matches: RefCell<HashMap<String, bool>>,
18}
19
20impl Payee {
21    pub fn new(
22        name: String,
23        note: Option<String>,
24        alias: HashSet<String>,
25        alias_regex: Vec<Regex>,
26        origin: Origin,
27    ) -> Payee {
28        Payee {
29            name,
30            note,
31            alias,
32            alias_regex,
33            origin,
34            matches: RefCell::new(HashMap::new()),
35        }
36    }
37    pub fn is_match(&self, regex: Regex) -> bool {
38        let mut list = self.matches.borrow_mut();
39        match list.get(regex.as_str()) {
40            Some(x) => *x,
41
42            None => {
43                let value = regex.is_match(self.get_name());
44                list.insert(regex.as_str().to_string(), value);
45                value
46            }
47        }
48    }
49    pub fn get_aliases(&self) -> &Vec<Regex> {
50        &self.alias_regex
51    }
52}
53impl Eq for Payee {}
54
55impl PartialEq for Payee {
56    fn eq(&self, other: &Self) -> bool {
57        self.name == other.name
58    }
59}
60
61impl Display for Payee {
62    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
63        write!(f, "{}", self.name)
64    }
65}
66
67impl HasName for Payee {
68    fn get_name(&self) -> &str {
69        self.name.as_str()
70    }
71}
72
73impl HasAliases for Payee {
74    fn get_aliases(&self) -> &HashSet<String, RandomState> {
75        &self.alias
76    }
77}
78
79impl FromDirective for Payee {
80    fn is_from_directive(&self) -> bool {
81        matches!(self.origin, Origin::FromDirective)
82    }
83}
84
85impl Hash for Payee {
86    fn hash<H: Hasher>(&self, state: &mut H) {
87        self.name.hash(state);
88    }
89}
90
91impl From<&str> for Payee {
92    fn from(name: &str) -> Self {
93        Payee::new(
94            String::from(name),
95            None,
96            Default::default(),
97            Default::default(),
98            Origin::FromTransaction,
99        )
100    }
101}