use crate::value::Value; use std::collections::HashMap; use std::ops::{Deref, DerefMut}; //TODO: editor integration, implement these traits for whatever is needed, maybe merge them if needed pub trait ValueProvider { fn get_value(&self, name: &str) -> Option; } pub trait FunctionProvider { fn run_function(&self, name: &str, args: &[Value]) -> Option; } pub struct ValueMap(HashMap); pub struct NothingMap; impl ValueProvider for &ValueMap { fn get_value(&self, name: &str) -> Option { self.0.get(name).cloned() } } impl ValueProvider for NothingMap { fn get_value(&self, _: &str) -> Option { None } } impl ValueProvider for ValueMap { fn get_value(&self, name: &str) -> Option { self.0.get(name).cloned() } } impl Deref for ValueMap { type Target = HashMap; fn deref(&self) -> &Self::Target { &self.0 } } impl DerefMut for ValueMap { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } impl FunctionProvider for NothingMap { fn run_function(&self, _: &str, _: &[Value]) -> Option { None } } pub struct EvalContext { values: V, functions: F, } impl Default for EvalContext { fn default() -> Self { Self { values: NothingMap, functions: NothingMap, } } } impl EvalContext { pub fn new(values: V, functions: F) -> Self { Self { values, functions } } pub fn get_value(&self, name: &str) -> Option { self.values.get_value(name) } pub fn run_function(&self, name: &str, args: &[Value]) -> Option { self.functions.run_function(name, args) } }