cel-rs 0.2.0

Common Expression Language (cel) for Rust.
Documentation
use crate::parser::Expression;
use crate::parser::cel::ExpressionParser;
use std::fmt;
use std::result::Result;
use crate::context::Context;
use crate::eval::{Bag, Eval};
use crate::Value;

pub struct Program {
    expr: Expression
}

#[derive(Debug)]
pub struct ParseError {
    message: String,
}


impl fmt::Display for ParseError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.message)
    }
}

impl Program {
    pub fn new(source: &str) -> Result<Program, ParseError> {
        match ExpressionParser::new().parse(source) {
            Ok(expr) => Ok(Program {expr}),
            Err(e) => Err(ParseError{message: format!("{}", e)}),
        }
    }

    pub fn execute(self, context: &mut Context) -> bool {
        self.eval(context).unpack().into()
    }

    pub fn eval(self, context: &mut Context) -> Value {
        let e = Eval::default();
        e.eval(self.expr, context).unpack()
    }
}



#[cfg(test)]
pub mod tests {
    use std::rc::Rc;

    use crate::{program, value::{FnValue, Overload}, Value};

    macro_rules! string {
        ($q:literal) => {
            crate::Value::String(std::rc::Rc::new($q.into()))
        };
    }
    macro_rules! eval_program {
        ($expr:literal) => ({
           eval_program!($expr, &mut crate::context::Context::default())
        });
        ($expr:literal, $ctx:expr) => ({
            let program = crate::program::Program::new($expr);
            assert!(program.is_ok(), "failed to create the program {:?}", program.err());
            let program = program.unwrap();
            program.eval($ctx)
        });
    }

    #[test]
    fn basic_test() {
        assert_eq!(eval_program!(r#"r"""#), string!(""));
    }

    fn calc_string_string(lhs: &Value, rhs: &Value) -> Value {
        Value::Null
    }

    #[test]
    fn fn_test() {
        let func = FnValue {
            name: "calc",
            overloads: &[
                Overload {
                    key: "calc_string",
                    func: calc_string_string
                }
            ],
        };
        let mut ctx = program::Context::default()
        .add_variable("a", Value::String(Rc::new("".into())))
        .add_variable("b", Value::Int(0))
        .add_variable("calc", crate::Value::Function(Rc::new(func)));
        assert_eq!(eval_program!(r#"b.calc(a)"#, &mut ctx), string!(""));
    }
}