lieval 0.2.5

A lightweight Rust crate for parsing and evaluating mathematical expressions from strings.
Documentation
use crate::eval::Expr;
use crate::error::EvalError;
use crate::token::Value;
#[cfg(not(feature="fxhash"))]
use std::collections::HashMap;
#[cfg(feature="fxhash")]
use fxhash::FxHashMap;

#[derive(Debug, Clone)]
pub struct FuncClosure {
    arg_len: usize,
    func: fn(&[Value]) -> Value
}

impl FuncClosure {
    pub(crate) fn new(f: fn(&[Value]) -> Value, n: usize) -> Self {
        Self {
            arg_len: n,
            func: f
        }
    }

    pub(crate) fn get_arg_len(&self) -> usize {
        self.arg_len
    }
    
    pub(crate) fn call(&self, x: &[Value]) -> Value {
        (self.func)(x)
    }
}

#[cfg(not(feature="fxhash"))]
#[derive(Debug, Clone, Default)]
pub struct Context {
    value_map: HashMap<String, Value>,
    func_map: HashMap<String, FuncClosure>,
}

#[cfg(feature="fxhash")]
#[derive(Debug, Clone, Default)]
pub struct Context {
    value_map: FxHashMap<String, Value>,
    func_map: FxHashMap<String, FuncClosure>,
}

impl Context {
    #[cfg(not(feature="fxhash"))]
    pub fn new() -> Self {
        Self {
            value_map: HashMap::new(),
            func_map: HashMap::new()
        }
    }

    #[cfg(feature="fxhash")]
    pub fn new() -> Self {
        Self {
            value_map: FxHashMap::default(),
            func_map: FxHashMap::default()
        }
    }

    pub fn set_value(&mut self, key: &str, val: Value) -> &mut Self {
        self.value_map.insert(key.to_owned(), val);
        self
    }

    pub fn get_value(&self, key: &str) -> Option<&Value> {
        self.value_map.get(key)
    }

    pub fn set_func(&mut self, key: &str, n: usize, f: fn(&[Value]) -> Value) -> &mut Self {
        self.func_map.insert(key.to_owned(), FuncClosure::new(f, n));
        self
    }

    pub fn get_func(&self, key: &str) -> Option<&FuncClosure> {
        self.func_map.get(key)
    }

    
    pub fn ctx_merge(lhs: &Context, rhs: &Context) -> Self {
        let mut value_map = rhs.value_map.clone();
        value_map.extend(lhs.value_map.clone());
        let mut func_map = rhs.func_map.clone();
        func_map.extend(lhs.func_map.clone());
        Self {
            value_map,
            func_map,
        }
    }

    pub fn eval(&mut self, expr: &str) -> Result<Value, EvalError> {
        Expr::new(expr)?.apply_context(self).eval()
    }

    pub fn evals(&mut self, expr: &str) -> Result<Vec<Value>, EvalError> {
        Expr::new(expr)?.apply_context(self).evals()
    }
}