use expression_core::expression::Expression;
use std::collections::HashMap;
pub fn parse(input: &str) -> Result<Expression, String> {
Expression::parse(input)
}
pub fn evaluate(input: &str, variables: &HashMap<String, f64>) -> Result<f64, String> {
parse(input)?.evaluate(variables)
}
pub fn create_function(
input: &str,
) -> Result<impl Fn(&[(&str, f64)]) -> Result<f64, String>, String> {
let expr = parse(input)?;
Ok(move |args: &[(&str, f64)]| {
let mut variables = HashMap::new();
for (name, value) in args {
variables.insert(name.to_string(), *value);
}
expr.evaluate(&variables)
})
}
#[doc(inline)]
pub use expression_macro::expr;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_and_evaluate() {
let mut vars = HashMap::new();
vars.insert("x".to_string(), 2.0);
let result = evaluate("x^2 + 3*x + 1", &vars).unwrap();
assert_eq!(result, 11.0);
}
#[test]
fn test_create_function() {
let f = create_function("sin(x) + cos(y)").unwrap();
let result = f(&[("x", 0.0), ("y", 0.0)]).unwrap();
assert_eq!(result, 1.0);
}
#[test]
fn test_expr_macro() {
let expr = expr!("2*x + y");
let mut vars = HashMap::new();
vars.insert("x".to_string(), 3.0);
vars.insert("y".to_string(), 1.0);
let result = expr.evaluate(&vars).unwrap();
assert_eq!(result, 7.0);
}
}