tenda_runtime/
environment.rs1use 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}