atc_router/
router.rs

1use crate::ast::Expression;
2use crate::context::{Context, Match};
3use crate::interpreter::Execute;
4use crate::parser::parse;
5use crate::schema::Schema;
6use crate::semantics::{FieldCounter, Validate};
7use std::collections::{BTreeMap, HashMap};
8use uuid::Uuid;
9
10#[derive(PartialEq, Eq, PartialOrd, Ord)]
11struct MatcherKey(usize, Uuid);
12
13pub struct Router<'a> {
14    schema: &'a Schema,
15    matchers: BTreeMap<MatcherKey, Expression>,
16    pub fields: HashMap<String, usize>,
17}
18
19impl<'a> Router<'a> {
20    pub fn new(schema: &'a Schema) -> Self {
21        Self {
22            schema,
23            matchers: BTreeMap::new(),
24            fields: HashMap::new(),
25        }
26    }
27
28    pub fn add_matcher(&mut self, priority: usize, uuid: Uuid, atc: &str) -> Result<(), String> {
29        let key = MatcherKey(priority, uuid);
30
31        if self.matchers.contains_key(&key) {
32            return Err("UUID already exists".to_string());
33        }
34
35        let ast = parse(atc).map_err(|e| e.to_string())?;
36
37        ast.validate(self.schema)?;
38        ast.add_to_counter(&mut self.fields);
39
40        assert!(self.matchers.insert(key, ast).is_none());
41
42        Ok(())
43    }
44
45    pub fn remove_matcher(&mut self, priority: usize, uuid: Uuid) -> bool {
46        let key = MatcherKey(priority, uuid);
47
48        if let Some(ast) = self.matchers.remove(&key) {
49            ast.remove_from_counter(&mut self.fields);
50            return true;
51        }
52
53        false
54    }
55
56    pub fn execute(&self, context: &mut Context) -> bool {
57        for (MatcherKey(_, id), m) in self.matchers.iter().rev() {
58            let mut mat = Match::new();
59            if m.execute(context, &mut mat) {
60                mat.uuid = *id;
61                context.result = Some(mat);
62
63                return true;
64            }
65        }
66
67        false
68    }
69}