Skip to main content

ganit_core/eval/context/
mod.rs

1use std::collections::HashMap;
2use crate::types::Value;
3
4/// Holds the named variable bindings for a formula evaluation.
5///
6/// All keys are stored and looked up in uppercase, so variable names are
7/// case-insensitive (`A1`, `a1`, and `A1` all refer to the same binding).
8pub struct Context {
9    pub vars: HashMap<String, Value>,
10}
11
12impl Context {
13    /// Create a `Context` from a map of variable name → value.
14    /// Keys are normalised to uppercase on insertion.
15    pub fn new(vars: HashMap<String, Value>) -> Self {
16        let normalized = vars.into_iter()
17            .map(|(k, v)| (k.to_uppercase(), v))
18            .collect();
19        Self { vars: normalized }
20    }
21
22    /// Create an empty `Context` with no variable bindings.
23    pub fn empty() -> Self {
24        Self { vars: HashMap::new() }
25    }
26
27    /// Look up a variable by name (case-insensitive). Returns `Value::Empty` if not found.
28    pub fn get(&self, name: &str) -> Value {
29        self.vars
30            .get(&name.to_uppercase())
31            .cloned()
32            .unwrap_or(Value::Empty)
33    }
34
35    /// Insert or overwrite a binding. Returns the previous value if one existed.
36    pub fn set(&mut self, name: String, value: Value) -> Option<Value> {
37        self.vars.insert(name.to_uppercase(), value)
38    }
39
40    /// Remove a binding. Used to restore context after lambda/let evaluation.
41    pub fn remove(&mut self, name: &str) {
42        self.vars.remove(&name.to_uppercase());
43    }
44}
45
46#[cfg(test)]
47mod tests;