sandl 0.1.0

A framework for building parallel execution engines with dependency management, type-safe method dispatch, and event observation.
Documentation
use crate::Value;
use std::collections::HashMap;
use std::sync::{Arc, RwLock};

#[derive(Clone, Debug)]
pub struct Context {
    data: Arc<RwLock<HashMap<String, Value>>>,
}

impl Context {
    pub fn new() -> Self {
        Self {
            data: Arc::new(RwLock::new(HashMap::new())),
        }
    }

    pub fn get(&self, key: &str) -> Option<Value> {
        self.data.read().unwrap().get(key).cloned()
    }

    pub fn set(&self, key: impl Into<String>, value: Value) {
        self.data.write().unwrap().insert(key.into(), value);
    }

    pub fn contains(&self, key: &str) -> bool {
        self.data.read().unwrap().contains_key(key)
    }

    pub fn remove(&self, key: &str) -> Option<Value> {
        self.data.write().unwrap().remove(key)
    }

    pub fn keys(&self) -> Vec<String> {
        self.data.read().unwrap().keys().cloned().collect()
    }

    pub fn clear(&self) {
        self.data.write().unwrap().clear();
    }

    pub fn len(&self) -> usize {
        self.data.read().unwrap().len()
    }

    pub fn is_empty(&self) -> bool {
        self.data.read().unwrap().is_empty()
    }

    pub fn get_as<T>(&self, key: &str) -> crate::Result<T>
    where
        T: crate::FromValue,
    {
        let value = self.get(key).ok_or_else(|| {
            crate::Error::ConfigError(format!("Key '{}' not found in context", key))
        })?;
        T::from_value(&value)
    }

    pub fn set_from<T>(&self, key: impl Into<String>, value: T)
    where
        T: crate::ToValue,
    {
        self.set(key, value.to_value());
    }
}

impl Default for Context {
    fn default() -> Self {
        Self::new()
    }
}