use std::any::Any;
use crate::ast::value::Value;
use crate::error::EvalError;
use crate::Registry;
pub trait EvalContext: Any {
fn resolve_variable(&self, scope: &str, name: &str) -> Result<Option<Value>, EvalError>;
fn set_variable(&mut self, scope: &str, name: &str, value: Value) -> Result<(), EvalError>;
fn fire_trigger(&mut self, entry_id: &str, registry: &Registry) -> Result<String, EvalError>;
fn resolve_document(&mut self, document_id: &str, registry: &Registry) -> Result<String, EvalError>;
}
pub struct SimpleContext {
variables: std::collections::HashMap<String, std::collections::HashMap<String, Value>>,
}
impl SimpleContext {
pub fn new() -> Self {
Self {
variables: std::collections::HashMap::new(),
}
}
pub fn set(&mut self, scope: &str, name: &str, value: impl Into<Value>) {
self.variables
.entry(scope.to_string())
.or_default()
.insert(name.to_string(), value.into());
}
}
impl Default for SimpleContext {
fn default() -> Self {
Self::new()
}
}
impl EvalContext for SimpleContext {
fn resolve_variable(&self, scope: &str, name: &str) -> Result<Option<Value>, EvalError> {
Ok(self
.variables
.get(scope)
.and_then(|vars| vars.get(name))
.cloned())
}
fn set_variable(&mut self, scope: &str, name: &str, value: Value) -> Result<(), EvalError> {
self.variables
.entry(scope.to_string())
.or_default()
.insert(name.to_string(), value);
Ok(())
}
fn fire_trigger(&mut self, entry_id: &str, _registry: &Registry) -> Result<String, EvalError> {
Err(EvalError::new(
crate::error::EvalErrorKind::TriggerNotFound,
format!("SimpleContext does not support triggers (tried: {entry_id})"),
))
}
fn resolve_document(&mut self, document_id: &str, _registry: &Registry) -> Result<String, EvalError> {
Err(EvalError::new(
crate::error::EvalErrorKind::DocumentNotFound,
format!("SimpleContext does not support documents (tried: {document_id})"),
))
}
}