tenda_runtime/
environment.rs

1use std::{cell::RefCell, collections::HashMap, rc::Rc};
2
3use super::value::Value;
4
5#[derive(Debug, Clone)]
6pub struct Environment {
7    state: HashMap<String, ValueCell>,
8}
9
10impl Environment {
11    pub fn new() -> Self {
12        Environment {
13            state: HashMap::new(),
14        }
15    }
16
17    pub fn get(&self, name: &str) -> Option<&ValueCell> {
18        self.state.get(name)
19    }
20
21    pub fn has(&self, name: &String) -> bool {
22        self.state.contains_key(name)
23    }
24
25    pub fn set(&mut self, name: String, value: ValueCell) {
26        match self.state.get_mut(&name) {
27            Some(val) => match val {
28                ValueCell::Shared(val) => {
29                    *val.borrow_mut() = value.extract();
30                }
31                ValueCell::Owned(_) => {
32                    self.state.insert(name, value);
33                }
34            },
35            None => {
36                self.state.insert(name, value);
37            }
38        }
39    }
40}
41
42impl<'a> IntoIterator for &'a Environment {
43    type Item = (&'a String, &'a ValueCell);
44    type IntoIter = std::collections::hash_map::Iter<'a, String, ValueCell>;
45
46    fn into_iter(self) -> Self::IntoIter {
47        self.state.iter()
48    }
49}
50
51impl Default for Environment {
52    fn default() -> Self {
53        Self::new()
54    }
55}
56
57#[derive(Debug, Clone)]
58pub enum ValueCell {
59    Owned(Value),
60    Shared(Rc<RefCell<Value>>),
61}
62
63impl ValueCell {
64    pub fn new(value: Value) -> Self {
65        ValueCell::Owned(value)
66    }
67
68    pub fn new_shared(value: Value) -> Self {
69        ValueCell::Shared(Rc::new(RefCell::new(value)))
70    }
71
72    pub fn extract(&self) -> Value {
73        match self {
74            ValueCell::Owned(val) => val.clone(),
75            ValueCell::Shared(val) => val.borrow().clone(),
76        }
77    }
78}