summaryrefslogtreecommitdiff
path: root/crimtag/src/context.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crimtag/src/context.rs')
-rw-r--r--crimtag/src/context.rs289
1 files changed, 289 insertions, 0 deletions
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 @@
1use std::collections::HashMap;
2use std::fmt;
3
4use crate::error::CrimResult;
5
6use crate::{Identifier,IdentifierValue};
7
8pub type Context = HashMap<String,Value>;
9
10pub trait MappedStructure<'a> {
11 fn get_value(&'a self, id: &str) -> Option<MappedValue<'a>>;
12}
13
14impl<'a> MappedStructure<'a> for Context {
15 fn get_value(&'a self, id: &str) -> Option<MappedValue<'a>> {
16 self.get(id).map(|v|Into::<MappedValue<'a>>::into(v))
17 }
18}
19
20pub trait MappedList<'a> {
21 fn get_index(&'a self, id: usize) -> Option<MappedValue<'a>>;
22 fn for_each(&'a self, func: &dyn Fn(&MappedValue<'a>, &mut String) -> CrimResult<()>) -> CrimResult<String>;
23}
24
25impl<'a, T: MappedStructure<'a>> MappedList<'a> for Vec<T> {
26 fn get_index(&'a self, id: usize) -> Option<MappedValue<'a>> {
27 if let Some(x) = self.get(id) {
28 Some(MappedValue::<'a>::Struct(x))
29 } else {
30 None
31 }
32 }
33
34 fn for_each(&'a self, func: &dyn Fn(&MappedValue<'a>, &mut String) -> CrimResult<()>) -> CrimResult<String> {
35 let mut buf = String::new();
36 for i in self {
37 func( &MappedValue::Struct(i), &mut buf )?;
38 }
39 Ok(buf)
40 }
41}
42
43impl<'a> MappedList<'a> for Vec<Value> {
44 fn get_index(&'a self, id: usize) -> Option<MappedValue<'a>> {
45 if let Some(x) = self.get(id) {
46 Some(x.into())
47 } else {
48 None
49 }
50 }
51
52 fn for_each(&'a self, func: &dyn Fn(&MappedValue<'a>, &mut String) -> CrimResult<()>) -> CrimResult<String> {
53 let mut buf = String::new();
54 for i in self {
55 func( &Into::<MappedValue<'a>>::into( i ), &mut buf )?;
56 }
57 Ok(buf)
58 }
59}
60
61impl<'a> MappedList<'a> for Vec<MappedValue<'a>> {
62 fn get_index(&'a self, id: usize) -> Option<MappedValue<'a>> {
63 if let Some(x) = self.get(id) {
64 Some(*x)
65 } else {
66 None
67 }
68 }
69
70 fn for_each(&'a self, func: &dyn Fn(&MappedValue<'a>, &mut String) -> CrimResult<()>) -> CrimResult<String> {
71 let mut buf = String::new();
72 for i in self {
73 func( i, &mut buf )?;
74 }
75 Ok(buf)
76 }
77}
78
79pub type MappedHash<'a> = HashMap<String, MappedValue<'a>>;
80
81impl<'a> MappedStructure<'a> for MappedHash<'a> {
82 fn get_value(&'a self, id: &str) -> Option<MappedValue<'a>> {
83 self.get(id).copied()
84 }
85}
86
87#[derive(Copy,Clone)]
88pub enum MappedValue<'a> {
89 Struct(&'a dyn MappedStructure<'a>),
90 List(&'a dyn MappedList<'a>),
91
92 Str(&'a str),
93 String(&'a String),
94 Int8(i8),
95 Int16(i16),
96 Int32(i32),
97 Int64(i64),
98 UInt8(u8),
99 UInt16(u16),
100 UInt32(u32),
101 UInt64(u64),
102 Float32(f32),
103 Float64(f64),
104 Bool(bool),
105}
106
107impl<'a> fmt::Debug for MappedValue<'a> {
108 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109 match self {
110 MappedValue::<'a>::Struct(_) => write!(f, "MappedValue"),
111 MappedValue::<'a>::List(_) => write!(f, "MappedList"),
112 MappedValue::<'a>::Str(v) => write!(f, "{:?}", v),
113 MappedValue::<'a>::String(v) => write!(f, "{:?}", v),
114 MappedValue::<'a>::Int8(v) => write!(f, "{:?}", v),
115 MappedValue::<'a>::Int16(v) => write!(f, "{:?}", v),
116 MappedValue::<'a>::Int32(v) => write!(f, "{:?}", v),
117 MappedValue::<'a>::Int64(v) => write!(f, "{:?}", v),
118 MappedValue::<'a>::UInt8(v) => write!(f, "{:?}", v),
119 MappedValue::<'a>::UInt16(v) => write!(f, "{:?}", v),
120 MappedValue::<'a>::UInt32(v) => write!(f, "{:?}", v),
121 MappedValue::<'a>::UInt64(v) => write!(f, "{:?}", v),
122 MappedValue::<'a>::Float32(v) => write!(f, "{:?}", v),
123 MappedValue::<'a>::Float64(v) => write!(f, "{:?}", v),
124 MappedValue::<'a>::Bool(v) => write!(f, "{:?}", v),
125 }
126 }
127
128}
129
130pub struct StatefulContext<'a> {
131 root: &'a dyn MappedStructure<'a>,
132 local: &'a dyn MappedStructure<'a>,
133}
134
135impl<'a> StatefulContext<'a> {
136 pub fn root( root: &'a dyn MappedStructure<'a> ) -> Self {
137 Self {
138 root, local: root,
139 }
140 }
141
142 pub fn local(&self, local: &'a dyn MappedStructure<'a> ) -> Self {
143 Self {
144 root: self.root,
145 local
146 }
147 }
148
149 pub fn full( root: &'a dyn MappedStructure<'a>, local: &'a dyn MappedStructure<'a> ) -> Self {
150 Self {
151 root, local
152 }
153 }
154
155 pub fn get_value(&self, id: &[IdentifierValue]) -> Option<MappedValue<'a>> {
156 let mut value : Option<MappedValue> =
157 if id[0] == IdentifierValue::Root {
158 Some(MappedValue::Struct(self.root))
159 } else {
160 Some(MappedValue::Struct(self.local))
161 };
162 for idpart in id {
163 match idpart {
164 IdentifierValue::Root => {
165 continue;
166 }
167 IdentifierValue::Name(name) => {
168 if let Some(MappedValue::Struct(s)) = value &&
169 let Some(nv) = s.get_value( &name ) {
170 value.replace( nv );
171 } else {
172 return None;
173 }
174 }
175 IdentifierValue::Index(_) => {
176 return None;
177 }
178 }
179 }
180 value
181 }
182}
183
184impl<'a> From<&'a Value> for MappedValue<'a> {
185 fn from(value: &'a Value) -> Self {
186 match value {
187 Value::Dictionary(ctx) => MappedValue::Struct(ctx),
188 Value::List(list) => MappedValue::List(list),
189 Value::String(s) => MappedValue::String(s),
190 Value::Int(i) => MappedValue::Int64(*i),
191 Value::Float(f) => MappedValue::Float64(*f),
192 Value::Bool(b) => MappedValue::Bool(*b),
193 Value::Identifier(_identifier) => panic!("Identifier!?"),
194 }
195 }
196}
197
198#[derive(Debug,Clone)]
199pub enum Value {
200 Dictionary(Context),
201 List(Vec<Value>),
202 String(String),
203 Int(i64),
204 Float(f64),
205 Bool(bool),
206 Identifier(Identifier),
207}
208
209impl From<&str> for Value {
210 fn from(val: &str ) -> Value {
211 Value::String(val.into())
212 }
213}
214
215impl From<String> for Value {
216 fn from(val: String) -> Value {
217 Value::String(val)
218 }
219}
220
221impl From<i64> for Value {
222 fn from(val: i64) -> Value {
223 Value::Int(val)
224 }
225}
226
227impl From<f64> for Value {
228 fn from(val: f64) -> Value {
229 Value::Float(val)
230 }
231}
232
233impl From<bool> for Value {
234 fn from(val: bool) -> Value {
235 Value::Bool(val)
236 }
237}
238
239impl From<Vec<Value>> for Value {
240 fn from(val: Vec<Value>) -> Value {
241 Value::List(val)
242 }
243}
244
245impl From<&[Value]> for Value {
246 fn from(val: &[Value]) -> Value {
247 Value::List(Vec::from(val))
248 }
249}
250
251impl From<Context> for Value {
252 fn from(val: Context) -> Value {
253 Value::Dictionary(val)
254 }
255}
256
257impl<const N: usize> From<[(String,Value); N]> for Value {
258 fn from(val: [(String,Value); N]) -> Value {
259 Value::Dictionary(HashMap::from(val))
260 }
261}
262
263/*
264impl MappedStructure for Value {
265 fn get_value(&self, id: &Identifier) -> Option<Value> {
266 if id.len() == 0 {
267 return Some(self);
268 }
269 match Value {
270 Value::Dictionary(dict) => {
271 }
272 }
273 let mut cur_val : Option<&Value> = Some(&self);
274
275 for idx in 0..id.len() {
276 if let IdentifierValue::Name(s) = &id[idx] &&
277 let Some(Value::Dictionary(d)) = &cur_val {
278 cur_val.replace( if let Some(v) = d.get(s) {
279 v
280 } else {
281 return None;
282 });
283 }
284 }
285
286 return cur_val.cloned();
287 }
288}
289*/