use std::collections::HashMap; use crate::{Identifier,IdentifierValue}; pub type Context = HashMap; pub trait MappedStructure { fn get_value(&self, id: &[IdentifierValue]) -> Option; fn get_iterable(&self, id: &[IdentifierValue]) -> Option where T: IntoIterator, T::Item: MappedStructure; } impl MappedStructure for Context { fn get_value(&self, id: &[IdentifierValue]) -> Option { if id.len() == 0 { return None; } let mut cur_val : Option<&Value> = if let IdentifierValue::Name(s) = &id[0] { self.get(s) } else { return None; }; if cur_val.is_none() { return None; } for idx in 1..id.len() { if let IdentifierValue::Name(s) = &id[idx] && let Some(Value::Dictionary(d)) = &cur_val { cur_val.replace( if let Some(v) = d.get(s) { v } else { return None; }); } } return cur_val.cloned(); } fn get_iter(&self, id: &[IdentifierValue]) -> Option where T: IntoIterator, T::Item: MappedStructure, { if id.len() == 0 { return None; } let mut cur_val : Option<&Value> = if let IdentifierValue::Name(s) = &id[0] { self.get(s) } else { return None; }; if cur_val.is_none() { return None; } for idx in 1..id.len() { if let IdentifierValue::Name(s) = &id[idx] && let Some(Value::Dictionary(d)) = &cur_val { cur_val.replace( if let Some(v) = d.get(s) { v } else { return None; }); } } if let Some(Value::List(l)) = cur_val { return l.into } return cur_val.cloned(); } } pub struct StatefulContext<'a, T: MappedStructure> { pub root: &'a T, local: &'a T, } impl<'a, T: MappedStructure> StatefulContext<'a, T> { pub fn root( root: &'a T ) -> Self { Self { root, local: root, } } pub fn local(&self, local: &'a T ) -> Self { Self { root: self.root, local } } pub fn full( root: &'a T, local: &'a T ) -> Self { Self { root, local } } } impl<'a, T: MappedStructure> MappedStructure for StatefulContext<'a,T> { fn get_value(&self, id: &[IdentifierValue]) -> Option { if id.is_empty() { return None; } if id[0] == IdentifierValue::Root { self.root.get_value( &id[1..] ) } else { self.local.get_value( id ) } } fn get_iter(&self, id: &[IdentifierValue]) -> Option where U: IntoIterator, U::Item: MappedStructure, { None } } #[derive(Debug,Clone)] pub enum Value { Dictionary(Context), List(Vec), String(String), Int(i64), Float(f64), Bool(bool), Identifier(Identifier), } impl From<&str> for Value { fn from(val: &str ) -> Value { Value::String(val.into()) } } impl From for Value { fn from(val: String) -> Value { Value::String(val) } } impl From for Value { fn from(val: i64) -> Value { Value::Int(val) } } impl From for Value { fn from(val: f64) -> Value { Value::Float(val) } } impl From for Value { fn from(val: bool) -> Value { Value::Bool(val) } } impl From> for Value { fn from(val: Vec) -> Value { Value::List(val) } } impl From<&[Value]> for Value { fn from(val: &[Value]) -> Value { Value::List(Vec::from(val)) } } impl From for Value { fn from(val: Context) -> Value { Value::Dictionary(val) } } impl From<[(String,Value); N]> for Value { fn from(val: [(String,Value); N]) -> Value { Value::Dictionary(HashMap::from(val)) } } /* impl MappedStructure for Value { fn get_value(&self, id: &Identifier) -> Option { if id.len() == 0 { return Some(self); } match Value { Value::Dictionary(dict) => { } } let mut cur_val : Option<&Value> = Some(&self); for idx in 0..id.len() { if let IdentifierValue::Name(s) = &id[idx] && let Some(Value::Dictionary(d)) = &cur_val { cur_val.replace( if let Some(v) = d.get(s) { v } else { return None; }); } } return cur_val.cloned(); } } */