1use crate::{
2 Map, PrimitiveShape, PrimitiveShapeType, PrimitiveValue, Shape, ShapeType, Value,
3 ValuePrimitiveType, ValueType,
4};
5use alloc::{string::String, vec};
6
7impl PrimitiveShape {
10 pub fn is_number(&self) -> bool {
12 matches!(
13 self,
14 PrimitiveShape::F64 | PrimitiveShape::F32 | PrimitiveShape::I64 | PrimitiveShape::U64
15 )
16 }
17
18 pub fn matching_shape(&self, other: &PrimitiveShape) -> bool {
20 self == other || self.is_number() == other.is_number()
21 }
22
23 pub fn get_highest_order_number(
25 type_a: &PrimitiveShape,
26 type_b: &PrimitiveShape,
27 ) -> PrimitiveShape {
28 if *type_a == PrimitiveShape::F64 || *type_b == PrimitiveShape::F64 {
29 PrimitiveShape::F64
30 } else if *type_a == PrimitiveShape::F32 || *type_b == PrimitiveShape::F32 {
31 PrimitiveShape::F32
32 } else if *type_a == PrimitiveShape::I64 || *type_b == PrimitiveShape::I64 {
33 PrimitiveShape::I64
34 } else {
35 PrimitiveShape::U64
36 }
37 }
38
39 fn merge(&mut self, other: &Self) {
40 if self.is_number() && other.is_number() {
41 *self = Self::get_highest_order_number(self, other);
42 } else if !self.matching_shape(other) {
43 panic!("shape mismatch: {:?} vs {:?}", self, other);
44 }
45 }
47}
48impl From<&PrimitiveShape> for usize {
49 fn from(shape: &PrimitiveShape) -> Self {
50 match shape {
51 PrimitiveShape::String => 0,
52 PrimitiveShape::U64 => 1,
53 PrimitiveShape::I64 => 2,
54 PrimitiveShape::F32 => 3,
55 PrimitiveShape::F64 => 4,
56 PrimitiveShape::Bool => 5,
57 PrimitiveShape::Null => 6,
58 }
59 }
60}
61impl From<usize> for PrimitiveShape {
62 fn from(num: usize) -> Self {
63 match num {
64 0 => PrimitiveShape::String,
65 1 => PrimitiveShape::U64,
66 2 => PrimitiveShape::I64,
67 3 => PrimitiveShape::F32,
68 4 => PrimitiveShape::F64,
69 5 => PrimitiveShape::Bool,
70 6 => PrimitiveShape::Null,
71 _ => panic!("unknown value: {}", num),
72 }
73 }
74}
75impl From<&PrimitiveValue> for PrimitiveShape {
76 fn from(val: &PrimitiveValue) -> Self {
77 match val {
78 PrimitiveValue::String(_) => PrimitiveShape::String,
79 PrimitiveValue::U64(_) => PrimitiveShape::U64,
80 PrimitiveValue::I64(_) => PrimitiveShape::I64,
81 PrimitiveValue::F32(_) => PrimitiveShape::F32,
82 PrimitiveValue::F64(_) => PrimitiveShape::F64,
83 PrimitiveValue::Bool(_) => PrimitiveShape::Bool,
84 PrimitiveValue::Null => PrimitiveShape::Null,
85 }
86 }
87}
88
89impl From<&ValuePrimitiveType> for PrimitiveShapeType {
92 fn from(val: &ValuePrimitiveType) -> Self {
93 match val {
94 ValuePrimitiveType::Primitive(prim) => PrimitiveShapeType::Primitive(prim.into()),
95 ValuePrimitiveType::NestedPrimitive(nested) => {
96 let mut nested_map = Map::new();
97 for (key, value) in nested.iter() {
98 nested_map.insert(key.into(), value.into());
99 }
100 PrimitiveShapeType::NestedPrimitive(nested_map)
101 }
102 }
103 }
104}
105impl PrimitiveShapeType {
106 fn merge(&mut self, other: &Self) {
107 match (self, other) {
108 (
109 PrimitiveShapeType::Primitive(self_prim),
110 PrimitiveShapeType::Primitive(other_prim),
111 ) => {
112 self_prim.merge(other_prim);
113 }
114 (
115 PrimitiveShapeType::NestedPrimitive(self_nested),
116 PrimitiveShapeType::NestedPrimitive(other_nested),
117 ) => {
118 for (key, value) in other_nested.iter() {
119 if self_nested.contains_key(key) {
120 self_nested.get_mut(key).unwrap().merge(value);
121 } else {
122 self_nested.insert(key.clone(), value.clone());
123 }
124 }
125 }
126 _ => panic!("shape mismatch"),
127 }
128 }
129}
130
131impl Default for ShapeType {
134 fn default() -> Self {
135 ShapeType::Primitive(PrimitiveShape::Null)
136 }
137}
138impl From<&ValueType> for ShapeType {
139 fn from(val: &ValueType) -> Self {
140 match val {
141 ValueType::Primitive(prim) => ShapeType::Primitive(prim.into()),
142 ValueType::Nested(nested) => {
143 let mut nested_map: Map<String, ShapeType> = Map::new();
144 for (key, value) in nested.iter() {
145 nested_map.insert(key.into(), value.into());
146 }
147 ShapeType::Nested(nested_map)
148 }
149 ValueType::Array(array) => {
150 let validated = validate_types(array);
151 ShapeType::Array(vec![validated])
152 }
153 }
154 }
155}
156impl ShapeType {
157 fn merge(&mut self, other: &Self) {
158 match (self, other) {
159 (Self::Primitive(a), Self::Primitive(b)) => a.merge(b),
160 (Self::Array(a), Self::Array(b)) => {
161 a.first_mut().unwrap().merge(b.first().unwrap());
162 }
163 (Self::Nested(a), Self::Nested(b)) => a.merge(b),
164 _ => panic!("Can't merge"),
165 };
166 }
167}
168
169impl From<&Value> for Shape {
172 fn from(val: &Value) -> Self {
173 let mut shape = Shape::new();
174 for (key, value) in val.iter() {
175 shape.insert(key.into(), value.into());
176 }
177
178 shape
179 }
180}
181impl From<&[Value]> for Shape {
182 fn from(val: &[Value]) -> Self {
183 let mut shape = Shape::new();
184 for v in val {
185 shape.merge(&(v.into()));
186 }
187 shape
188 }
189}
190impl Shape {
191 pub fn merge(&mut self, other: &Self) {
193 for (key, value) in other.iter() {
194 self.entry(key.clone())
195 .and_modify(|val| val.merge(value))
196 .or_insert_with(|| value.clone());
197 }
198 }
199}
200
201impl PrimitiveValue {
204 pub fn default_from_shape(shape: &PrimitiveShape) -> Self {
206 match shape {
207 PrimitiveShape::String => PrimitiveValue::String(String::new()),
208 PrimitiveShape::U64 => PrimitiveValue::U64(0),
209 PrimitiveShape::I64 => PrimitiveValue::I64(0),
210 PrimitiveShape::F32 => PrimitiveValue::F32(0.0),
211 PrimitiveShape::F64 => PrimitiveValue::F64(0.0),
212 PrimitiveShape::Bool => PrimitiveValue::Bool(false),
213 PrimitiveShape::Null => PrimitiveValue::Null,
214 }
215 }
216
217 fn matching_shape(&self, other: &PrimitiveValue) -> bool {
218 matches!(
219 (self, other),
220 (PrimitiveValue::String(_), PrimitiveValue::String(_))
221 | (PrimitiveValue::U64(_), PrimitiveValue::U64(_))
222 | (PrimitiveValue::I64(_), PrimitiveValue::I64(_))
223 | (PrimitiveValue::F32(_), PrimitiveValue::F32(_))
224 | (PrimitiveValue::F64(_), PrimitiveValue::F64(_))
225 | (PrimitiveValue::Bool(_), PrimitiveValue::Bool(_))
226 | (PrimitiveValue::Null, PrimitiveValue::Null)
227 )
228 }
229}
230impl From<&PrimitiveValue> for PrimitiveValue {
231 fn from(mval: &PrimitiveValue) -> Self {
232 match mval {
233 PrimitiveValue::String(string) => PrimitiveValue::String(string.clone()),
234 PrimitiveValue::U64(usigned) => PrimitiveValue::U64(*usigned),
235 PrimitiveValue::I64(signed) => PrimitiveValue::I64(*signed),
236 PrimitiveValue::F32(float) => PrimitiveValue::F32(*float),
237 PrimitiveValue::F64(double) => PrimitiveValue::F64(*double),
238 PrimitiveValue::Bool(boolean) => PrimitiveValue::Bool(*boolean),
239 PrimitiveValue::Null => PrimitiveValue::Null,
240 }
241 }
242}
243
244impl ValuePrimitiveType {
247 fn same_nested(&self, nested: &Map<String, PrimitiveValue>) -> bool {
248 match self {
249 ValuePrimitiveType::Primitive(_) => false,
250 ValuePrimitiveType::NestedPrimitive(val) => {
251 for (key, val) in val.iter() {
252 if !val.matching_shape(nested.get(key).unwrap()) {
253 return false;
254 }
255 }
256 true
257 }
258 }
259 }
260}
261
262impl ValueType {
265 pub fn default_from_shape(shape: &ShapeType) -> Self {
267 match shape {
268 ShapeType::Primitive(shape) => {
269 ValueType::Primitive(PrimitiveValue::default_from_shape(shape))
270 }
271 ShapeType::Array(_) => ValueType::Array(vec![]),
272 ShapeType::Nested(shape) => ValueType::Nested(Value::default_from_shape(shape)),
273 }
274 }
275}
276impl From<&PrimitiveValue> for ValueType {
277 fn from(mval: &PrimitiveValue) -> Self {
278 ValueType::Primitive(mval.into())
279 }
280}
281impl From<&ValueType> for PrimitiveValue {
282 fn from(val: &ValueType) -> Self {
283 match val {
284 ValueType::Primitive(val) => val.into(),
285 _ => PrimitiveValue::Null,
286 }
287 }
288}
289
290impl Value {
293 pub fn default_from_shape(shape: &Shape) -> Self {
295 let mut value = Value::new();
296 for (key, shape_type) in shape.iter() {
297 value.insert(key.into(), ValueType::default_from_shape(shape_type));
298 }
299 value
300 }
301}
302
303pub fn validate_types(types: &[ValuePrimitiveType]) -> PrimitiveShapeType {
312 match types.first() {
313 Some(ValuePrimitiveType::Primitive(primitive)) => {
314 let mut base: PrimitiveShape = primitive.into();
315 let is_number = base.is_number();
316 for t in types {
317 match t {
318 ValuePrimitiveType::Primitive(t_prim) => {
319 let prim_shape = t_prim.into();
320 if !base.matching_shape(&prim_shape) {
321 panic!("All types must be the same");
322 } else if is_number {
323 base = PrimitiveShape::get_highest_order_number(&base, &prim_shape);
324 }
325 }
327 _ => panic!("All types must be the same"),
328 }
329 }
330
331 PrimitiveShapeType::Primitive(base)
332 }
333 Some(ValuePrimitiveType::NestedPrimitive(nested)) => {
334 for t in types[1..].iter() {
336 if !t.same_nested(nested) {
337 panic!("All types must be the same");
338 }
339 }
340
341 (&ValuePrimitiveType::NestedPrimitive(nested.clone())).into()
342 }
343 None => PrimitiveShapeType::Primitive(PrimitiveShape::Null),
344 }
345}