1use crate::rule::Rule;
2use std::sync::{Arc, Mutex};
3
4pub struct When<I, O> {
5 input: I,
6 rules: Arc<Mutex<Vec<Rule<I, O>>>>,
7}
8
9impl<I, O> When<I, O> {
10 pub(crate) fn new(input: I, rules: Arc<Mutex<Vec<Rule<I, O>>>>) -> Self {
11 When { input, rules }
12 }
13}
14
15impl<I: PartialEq, O> When<I, O> {
16 pub fn will_return(self, value: O) {
19 let mut rules_locked = self.rules.lock().unwrap();
20 let when_value = rules_locked
21 .iter()
22 .enumerate()
23 .find(|(_i, value)| value.input == self.input);
24
25 let rule = Rule::new(self.input, value);
26 match when_value {
27 Some((index, _value)) => {
28 let _old_rule = std::mem::replace(&mut rules_locked[index], rule);
29 ()
30 }
31 None => rules_locked.push(rule),
32 }
33 }
34}
35
36impl<I: PartialEq, O: Default> When<I, O> {
37 pub fn will_return_default(self) {
39 self.will_return(O::default())
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use super::When;
46 use crate::rule::Rule;
47 use std::sync::{Arc, Mutex};
48
49 #[test]
52 fn add_rule_to_list() {
53 let rules = Arc::new(Mutex::new(Vec::new()));
54 let when = When::new("hello", rules.clone());
55
56 when.will_return(true);
57
58 let rules = rules.lock().unwrap();
59 assert_eq!(*rules, vec![Rule::new("hello", true)]);
60 }
61
62 #[test]
63 fn when_input_already_match_another_rule_replace_old_rule() {
64 let rules = Arc::new(Mutex::new(Vec::new()));
65 let when = When::new("sameinput", rules.clone());
66
67 let assert_rule = |input, output| {
68 let rules_locked = rules.lock().unwrap();
69 let rule = rules_locked.get(0).unwrap();
70 assert_eq!(rules_locked.len(), 1, "Rules should have only one rule.");
71 assert_eq!(rule.input, input);
72 assert_eq!(rule.output, output);
73 };
74
75 when.will_return("rule1");
76 assert_rule("sameinput", "rule1");
77
78 let when = When::new("sameinput", rules.clone());
79 when.will_return("rule2");
80 assert_rule("sameinput", "rule2");
81 }
82
83 #[test]
86 fn add_default() {
87 let rules = Arc::new(Mutex::new(Vec::new()));
88 let when: When<&str, bool> = When::new("hello", rules.clone());
89
90 when.will_return_default();
91
92 let rules = rules.lock().unwrap();
93 assert_eq!(*rules, vec![Rule::new("hello", false)]);
94 }
95}