From 062048ef6e3e060bcf841ea2ec92e026f09d8da0 Mon Sep 17 00:00:00 2001 From: eichlan Date: Tue, 23 Jun 2026 15:31:51 -0700 Subject: Roorganized into workspace and packages. This is to accomidate a new proc_macro package, which can't have anything else in it. --- crimtag/src/context.rs | 289 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 289 insertions(+) create mode 100644 crimtag/src/context.rs (limited to 'crimtag/src/context.rs') diff --git a/crimtag/src/context.rs b/crimtag/src/context.rs new file mode 100644 index 0000000..6f8e04f --- /dev/null +++ b/crimtag/src/context.rs @@ -0,0 +1,289 @@ +use std::collections::HashMap; +use std::fmt; + +use crate::error::CrimResult; + +use crate::{Identifier,IdentifierValue}; + +pub type Context = HashMap; + +pub trait MappedStructure<'a> { + fn get_value(&'a self, id: &str) -> Option>; +} + +impl<'a> MappedStructure<'a> for Context { + fn get_value(&'a self, id: &str) -> Option> { + self.get(id).map(|v|Into::>::into(v)) + } +} + +pub trait MappedList<'a> { + fn get_index(&'a self, id: usize) -> Option>; + fn for_each(&'a self, func: &dyn Fn(&MappedValue<'a>, &mut String) -> CrimResult<()>) -> CrimResult; +} + +impl<'a, T: MappedStructure<'a>> MappedList<'a> for Vec { + fn get_index(&'a self, id: usize) -> Option> { + if let Some(x) = self.get(id) { + Some(MappedValue::<'a>::Struct(x)) + } else { + None + } + } + + fn for_each(&'a self, func: &dyn Fn(&MappedValue<'a>, &mut String) -> CrimResult<()>) -> CrimResult { + let mut buf = String::new(); + for i in self { + func( &MappedValue::Struct(i), &mut buf )?; + } + Ok(buf) + } +} + +impl<'a> MappedList<'a> for Vec { + fn get_index(&'a self, id: usize) -> Option> { + if let Some(x) = self.get(id) { + Some(x.into()) + } else { + None + } + } + + fn for_each(&'a self, func: &dyn Fn(&MappedValue<'a>, &mut String) -> CrimResult<()>) -> CrimResult { + let mut buf = String::new(); + for i in self { + func( &Into::>::into( i ), &mut buf )?; + } + Ok(buf) + } +} + +impl<'a> MappedList<'a> for Vec> { + fn get_index(&'a self, id: usize) -> Option> { + if let Some(x) = self.get(id) { + Some(*x) + } else { + None + } + } + + fn for_each(&'a self, func: &dyn Fn(&MappedValue<'a>, &mut String) -> CrimResult<()>) -> CrimResult { + let mut buf = String::new(); + for i in self { + func( i, &mut buf )?; + } + Ok(buf) + } +} + +pub type MappedHash<'a> = HashMap>; + +impl<'a> MappedStructure<'a> for MappedHash<'a> { + fn get_value(&'a self, id: &str) -> Option> { + self.get(id).copied() + } +} + +#[derive(Copy,Clone)] +pub enum MappedValue<'a> { + Struct(&'a dyn MappedStructure<'a>), + List(&'a dyn MappedList<'a>), + + Str(&'a str), + String(&'a String), + Int8(i8), + Int16(i16), + Int32(i32), + Int64(i64), + UInt8(u8), + UInt16(u16), + UInt32(u32), + UInt64(u64), + Float32(f32), + Float64(f64), + Bool(bool), +} + +impl<'a> fmt::Debug for MappedValue<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + MappedValue::<'a>::Struct(_) => write!(f, "MappedValue"), + MappedValue::<'a>::List(_) => write!(f, "MappedList"), + MappedValue::<'a>::Str(v) => write!(f, "{:?}", v), + MappedValue::<'a>::String(v) => write!(f, "{:?}", v), + MappedValue::<'a>::Int8(v) => write!(f, "{:?}", v), + MappedValue::<'a>::Int16(v) => write!(f, "{:?}", v), + MappedValue::<'a>::Int32(v) => write!(f, "{:?}", v), + MappedValue::<'a>::Int64(v) => write!(f, "{:?}", v), + MappedValue::<'a>::UInt8(v) => write!(f, "{:?}", v), + MappedValue::<'a>::UInt16(v) => write!(f, "{:?}", v), + MappedValue::<'a>::UInt32(v) => write!(f, "{:?}", v), + MappedValue::<'a>::UInt64(v) => write!(f, "{:?}", v), + MappedValue::<'a>::Float32(v) => write!(f, "{:?}", v), + MappedValue::<'a>::Float64(v) => write!(f, "{:?}", v), + MappedValue::<'a>::Bool(v) => write!(f, "{:?}", v), + } + } + +} + +pub struct StatefulContext<'a> { + root: &'a dyn MappedStructure<'a>, + local: &'a dyn MappedStructure<'a>, +} + +impl<'a> StatefulContext<'a> { + pub fn root( root: &'a dyn MappedStructure<'a> ) -> Self { + Self { + root, local: root, + } + } + + pub fn local(&self, local: &'a dyn MappedStructure<'a> ) -> Self { + Self { + root: self.root, + local + } + } + + pub fn full( root: &'a dyn MappedStructure<'a>, local: &'a dyn MappedStructure<'a> ) -> Self { + Self { + root, local + } + } + + pub fn get_value(&self, id: &[IdentifierValue]) -> Option> { + let mut value : Option = + if id[0] == IdentifierValue::Root { + Some(MappedValue::Struct(self.root)) + } else { + Some(MappedValue::Struct(self.local)) + }; + for idpart in id { + match idpart { + IdentifierValue::Root => { + continue; + } + IdentifierValue::Name(name) => { + if let Some(MappedValue::Struct(s)) = value && + let Some(nv) = s.get_value( &name ) { + value.replace( nv ); + } else { + return None; + } + } + IdentifierValue::Index(_) => { + return None; + } + } + } + value + } +} + +impl<'a> From<&'a Value> for MappedValue<'a> { + fn from(value: &'a Value) -> Self { + match value { + Value::Dictionary(ctx) => MappedValue::Struct(ctx), + Value::List(list) => MappedValue::List(list), + Value::String(s) => MappedValue::String(s), + Value::Int(i) => MappedValue::Int64(*i), + Value::Float(f) => MappedValue::Float64(*f), + Value::Bool(b) => MappedValue::Bool(*b), + Value::Identifier(_identifier) => panic!("Identifier!?"), + } + } +} + +#[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(); + } +} +*/ -- cgit v1.2.3