1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
use crate::functions;
use crate::objects::CelType;
use cel_parser::Expression;
use std::collections::HashMap;

pub struct Context {
    pub variables: HashMap<String, CelType>,
    pub functions:
        HashMap<String, Box<dyn Fn(Option<&CelType>, &[Expression], &Context) -> CelType>>,
}

impl Context {
    pub fn add_variable(&mut self, name: String, value: CelType) {
        self.variables.insert(name, value);
    }

    pub fn add_function<F: 'static>(&mut self, name: String, value: F)
    where
        F: Fn(Option<&CelType>, &[Expression], &Context) -> CelType,
    {
        self.functions.insert(name, Box::new(value));
    }
}

impl Default for Context {
    fn default() -> Self {
        let mut ctx = Context {
            variables: Default::default(),
            functions: Default::default(),
        };

        ctx.add_function("size".into(), |target, expr, context| {
            functions::size(target, expr, context)
        });

        ctx
    }
}