1#![allow(clippy::unwrap_used)]
2use super::ConversionError;
17
18use std::{
19 collections::BTreeMap,
20 ops::{Index, IndexMut},
21};
22
23use crate::evaluation::variable_value::{float::Float, integer::Integer, VariableValue};
24
25use std::sync::Arc;
26
27use ordered_float::OrderedFloat;
28
29#[derive(Debug, Clone, Hash, Eq, PartialEq, Default)]
30pub enum ElementValue {
31 #[default]
32 Null,
33 Bool(bool),
34 Float(OrderedFloat<f64>),
35 Integer(i64),
36 String(Arc<str>),
37 List(Vec<ElementValue>),
38 Object(ElementPropertyMap),
39}
40
41impl From<&ElementPropertyMap> for VariableValue {
42 fn from(val: &ElementPropertyMap) -> Self {
43 let mut map = BTreeMap::new();
44 for (key, value) in val.values.iter() {
45 map.insert(key.to_string(), value.into());
46 }
47 VariableValue::Object(map)
48 }
49}
50
51impl From<&ElementValue> for VariableValue {
52 fn from(val: &ElementValue) -> Self {
53 match val {
54 ElementValue::Null => VariableValue::Null,
55 ElementValue::Bool(b) => VariableValue::Bool(*b),
56 ElementValue::Float(f) => VariableValue::Float(Float::from(f.0)),
57 ElementValue::Integer(i) => VariableValue::Integer(Integer::from(*i)),
58 ElementValue::String(s) => VariableValue::String(s.to_string()),
59 ElementValue::List(l) => VariableValue::List(l.iter().map(|x| x.into()).collect()),
60 ElementValue::Object(o) => o.into(),
61 }
62 }
63}
64
65impl TryInto<ElementValue> for &VariableValue {
66 type Error = ConversionError;
67
68 fn try_into(self) -> Result<ElementValue, ConversionError> {
69 match self {
70 VariableValue::Null => Ok(ElementValue::Null),
71 VariableValue::Bool(b) => Ok(ElementValue::Bool(*b)),
72 VariableValue::Float(f) => Ok(ElementValue::Float(OrderedFloat(
73 f.as_f64().unwrap_or_default(),
74 ))),
75 VariableValue::Integer(i) => Ok(ElementValue::Integer(i.as_i64().unwrap_or_default())),
76 VariableValue::String(s) => Ok(ElementValue::String(Arc::from(s.as_str()))),
77 VariableValue::List(l) => Ok(ElementValue::List(
78 l.iter().map(|x| x.try_into().unwrap_or_default()).collect(),
79 )),
80 VariableValue::Object(o) => Ok(ElementValue::Object(o.into())),
81 _ => Err(ConversionError {}),
82 }
83 }
84}
85
86impl From<&ElementValue> for serde_json::Value {
87 fn from(val: &ElementValue) -> Self {
88 match val {
89 ElementValue::Null => serde_json::Value::Null,
90 ElementValue::Bool(b) => serde_json::Value::Bool(*b),
91 ElementValue::Float(f) => {
92 serde_json::Value::Number(serde_json::Number::from_f64(f.into_inner()).unwrap())
93 }
94 ElementValue::Integer(i) => serde_json::Value::Number(serde_json::Number::from(*i)),
95 ElementValue::String(s) => serde_json::Value::String(s.to_string()),
96 ElementValue::List(l) => serde_json::Value::Array(l.iter().map(|x| x.into()).collect()),
97 ElementValue::Object(o) => serde_json::Value::Object(o.into()),
98 }
99 }
100}
101
102impl From<&serde_json::Value> for ElementValue {
103 fn from(value: &serde_json::Value) -> Self {
104 match value {
105 serde_json::Value::Null => ElementValue::Null,
106 serde_json::Value::Bool(b) => ElementValue::Bool(*b),
107 serde_json::Value::Number(n) => {
108 if let Some(i) = n.as_i64() {
109 ElementValue::Integer(i)
110 } else if let Some(f) = n.as_f64() {
111 ElementValue::Float(OrderedFloat(f))
112 } else {
113 ElementValue::Null
114 }
115 }
116 serde_json::Value::String(s) => ElementValue::String(Arc::from(s.as_str())),
117 serde_json::Value::Array(a) => ElementValue::List(a.iter().map(|x| x.into()).collect()),
118 serde_json::Value::Object(o) => ElementValue::Object(o.into()),
119 }
120 }
121}
122
123impl TryInto<ElementPropertyMap> for &VariableValue {
124 type Error = ConversionError;
125
126 fn try_into(self) -> Result<ElementPropertyMap, ConversionError> {
127 match self {
128 VariableValue::Object(o) => {
129 let mut values = BTreeMap::new();
130 for (key, value) in o.iter() {
131 values.insert(Arc::from(key.as_str()), value.try_into()?);
132 }
133 Ok(ElementPropertyMap { values })
134 }
135 _ => Err(ConversionError {}),
136 }
137 }
138}
139
140#[derive(Debug, Clone, Hash, Eq, PartialEq)]
141pub struct ElementPropertyMap {
142 values: BTreeMap<Arc<str>, ElementValue>,
143}
144
145impl Default for ElementPropertyMap {
146 fn default() -> Self {
147 Self::new()
148 }
149}
150
151impl ElementPropertyMap {
152 pub fn new() -> Self {
153 ElementPropertyMap {
154 values: BTreeMap::new(),
155 }
156 }
157
158 pub fn get(&self, key: &str) -> Option<&ElementValue> {
159 self.values.get(key)
160 }
161
162 pub fn insert(&mut self, key: &str, value: ElementValue) {
163 self.values.insert(Arc::from(key), value);
164 }
165
166 pub fn merge(&mut self, other: &ElementPropertyMap) {
167 for (key, value) in other.values.iter() {
168 self.values
169 .entry(key.clone())
170 .or_insert_with(|| value.clone());
171 }
172 }
173
174 pub fn map_iter<T>(
175 &self,
176 f: impl Fn(&Arc<str>, &ElementValue) -> T + 'static,
177 ) -> impl Iterator<Item = T> + '_ {
178 self.values.iter().map(move |(k, v)| f(k, v))
179 }
180}
181
182impl Index<&str> for ElementPropertyMap {
183 type Output = ElementValue;
184
185 fn index(&self, key: &str) -> &Self::Output {
186 static NULL: ElementValue = ElementValue::Null;
187 match self.values.get(key) {
188 Some(value) => value,
189 None => &NULL,
190 }
191 }
192}
193
194impl IndexMut<&str> for ElementPropertyMap {
195 fn index_mut(&mut self, key: &str) -> &mut Self::Output {
196 self.values
197 .entry(Arc::from(key))
198 .or_insert_with(|| ElementValue::Null)
199 }
200}
201
202impl From<&BTreeMap<String, VariableValue>> for ElementPropertyMap {
203 fn from(map: &BTreeMap<String, VariableValue>) -> Self {
204 let mut values = BTreeMap::new();
205 for (key, value) in map.iter() {
206 values.insert(Arc::from(key.as_str()), value.try_into().unwrap());
207 }
208 ElementPropertyMap { values }
209 }
210}
211
212impl From<&ElementPropertyMap> for serde_json::Map<String, serde_json::Value> {
213 fn from(val: &ElementPropertyMap) -> Self {
214 val.values
215 .iter()
216 .map(|(k, v)| (k.to_string(), v.into()))
217 .collect()
218 }
219}
220
221impl From<&serde_json::Map<String, serde_json::Value>> for ElementPropertyMap {
222 fn from(map: &serde_json::Map<String, serde_json::Value>) -> Self {
223 let mut values = BTreeMap::new();
224 for (key, value) in map.iter() {
225 values.insert(Arc::from(key.as_str()), value.into());
226 }
227 ElementPropertyMap { values }
228 }
229}
230
231impl From<serde_json::Value> for ElementPropertyMap {
232 fn from(value: serde_json::Value) -> Self {
233 match value {
234 serde_json::Value::Object(o) => (&o).into(),
235 _ => ElementPropertyMap::new(),
236 }
237 }
238}