sunflower/src/env.rs

69 lines
1.6 KiB
Rust

use std::{
collections::HashMap,
sync::{Arc, RwLock},
};
use crate::value::Value;
#[derive(Debug, Clone)]
pub struct Env<'env> {
values: Arc<RwLock<HashMap<String, Value>>>,
parent: Option<&'env Env<'env>>,
}
impl Env<'_> {
pub fn new() -> Self {
Env {
values: Arc::default(),
parent: None,
}
}
pub fn get(&self, name: &str) -> Option<Value> {
if let Some(v) = self.values.read().unwrap().get(name) {
Some(v.clone())
} else if let Some(parent) = &self.parent {
parent.get(name)
} else {
None
}
}
pub fn set_here(&self, name: &str, value: Value) {
self.values.write().unwrap().insert(name.to_string(), value);
}
pub fn set(&self, name: &str, value: impl Into<Value>) {
let value = value.into();
if !self.set_recursive(name, &value) {
self.values.write().unwrap().insert(name.to_string(), value);
}
}
fn set_recursive(&self, name: &str, value: &Value) -> bool {
if let Some(v) = self.values.write().unwrap().get_mut(name) {
*v = value.clone();
true
} else if let Some(parent) = self.parent {
parent.set_recursive(name, value)
} else {
false
}
}
}
impl Default for Env<'_> {
fn default() -> Self {
Self::new()
}
}
impl<'env> Env<'env> {
pub fn new_with_parent(parent: &'env Env<'env>) -> Self {
Env {
values: Arc::default(),
parent: Some(parent),
}
}
}