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}