use super::*;
pub trait Env {
fn function(&self, name: &str) -> Result<Function, ErrorKind>;
fn value(&self, name: &str) -> Result<Value, ErrorKind>;
fn set_value(&mut self, name: &str, value: Value) -> Result<(), ErrorKind>;
}
pub type Value = f64;
pub type Function = fn(env: &dyn Env, vals: &mut [Value]) -> Result<Value, ErrorKind>;
pub fn function(name: &str) -> Option<Function> {
let function = match name {
"" => native::id,
"add" => native::add,
"sub" => native::sub,
"mul" => native::mul,
"div" => native::div,
"rem" => native::rem,
"pow" => native::pow,
"round" => native::round,
"floor" => native::floor,
"ceil" => native::ceil,
"trunc" => native::trunc,
"fract" => native::fract,
"abs" => native::abs,
"sign" => native::sign,
"sqr" => native::sqr,
"sqrt" => native::sqrt,
"cube" => native::cube,
"cbrt" => native::cbrt,
"isinf" => native::isinf,
"isnan" => native::isnan,
"min" => native::min,
"max" => native::max,
"clamp" => native::clamp,
"step" => native::step,
"smoothstep" => native::smoothstep,
"smootherstep" => native::smootherstep,
"eq" => native::eq,
"ne" => native::ne,
"gt" => native::gt,
"ge" => native::ge,
"lt" => native::lt,
"le" => native::le,
"all" => native::all,
"any" => native::any,
"not" => native::not,
"select" => native::select,
"exp" => native::exp,
"exp2" => native::exp2,
"expm1" => native::expm1,
"log" => native::log,
"log10" => native::log10,
"log2" => native::log2,
"ln" => native::ln,
"ln1p" => native::ln1p,
"mean" => native::mean,
"median" => native::median,
"range" => native::range,
"var" => native::var,
"stdev" => native::stdev,
"deg" => native::deg,
"rad" => native::rad,
"sin" => native::sin,
"cos" => native::cos,
"tan" => native::tan,
"asin" => native::asin,
"acos" => native::acos,
"atan" => native::atan,
"atan2" => native::atan2,
"sinh" => native::sinh,
"cosh" => native::cosh,
"tanh" => native::tanh,
"asinh" => native::asinh,
"acosh" => native::acosh,
"atanh" => native::atanh,
_ => return None,
};
Some(function)
}
#[derive(Clone, Default)]
pub struct BasicEnv {
pub ans: Value,
}
impl Env for BasicEnv {
fn function(&self, name: &str) -> Result<Function, ErrorKind> {
function(name).ok_or(ErrorKind::NameNotFound)
}
fn value(&self, name: &str) -> Result<Value, ErrorKind> {
let value = match name {
"ans" => self.ans,
"e" => f64::consts::E,
"pi" => f64::consts::PI,
"tau" => f64::consts::TAU,
_ => return Err(ErrorKind::NameNotFound),
};
Ok(value)
}
fn set_value(&mut self, name: &str, value: Value) -> Result<(), ErrorKind> {
match name {
"ans" => self.ans = value,
_ => return Err(ErrorKind::NameNotFound),
}
Ok(())
}
}
#[test]
fn var() {
let mut env = BasicEnv::default();
env.set_value("ans", 12.4).unwrap();
assert_eq!(env.value("ans"), Ok(12.4));
assert_eq!(env.value("pi"), Ok(f64::consts::PI));
assert_eq!(env.value("unknown"), Err(ErrorKind::NameNotFound));
assert_eq!(env.value("mean"), Err(ErrorKind::NameNotFound));
}