1use crate::{
2 dif::{
3 r#type::{DIFType, DIFTypeDefinition},
4 value::{DIFReferenceNotFoundError, DIFValueContainer},
5 },
6 libs::core::{CoreLibPointerId, get_core_lib_type_definition},
7 runtime::memory::Memory,
8 types::structural_type_definition::StructuralTypeDefinition,
9 values::{
10 core_value::CoreValue,
11 core_values::{
12 decimal::typed_decimal::{DecimalTypeVariant, TypedDecimal},
13 integer::Integer,
14 map::Map,
15 },
16 value::Value,
17 value_container::ValueContainer,
18 },
19};
20
21use crate::{
22 prelude::*, values::core_values::integer::typed_integer::TypedInteger,
23};
24use core::{cell::RefCell, fmt, result::Result};
25use indexmap::IndexMap;
26use ordered_float::OrderedFloat;
27use serde::{
28 Deserialize, Deserializer, Serialize, Serializer, de,
29 de::{MapAccess, SeqAccess, Visitor},
30 ser::{SerializeMap, SerializeSeq},
31};
32
33#[derive(Clone, Debug, PartialEq)]
34pub enum DIFValueRepresentation {
35 Null,
36 Boolean(bool),
38 String(String),
40 Number(f64),
42 Array(Vec<DIFValueContainer>),
44 Map(Vec<(DIFValueContainer, DIFValueContainer)>),
46 Object(Vec<(String, DIFValueContainer)>),
48}
49
50#[derive(Clone, Debug, PartialEq)]
51pub enum DIFTypeRepresentation {
52 Null,
53 Boolean(bool),
55 String(String),
57 Number(f64),
59 Array(Vec<DIFType>),
61 Map(Vec<(DIFType, DIFType)>),
63 Object(Vec<(String, DIFType)>),
65}
66
67impl DIFValueRepresentation {
68 pub fn to_default_value(
71 &self,
72 memory: &RefCell<Memory>,
73 ) -> Result<Value, DIFReferenceNotFoundError> {
74 Ok(match self {
75 DIFValueRepresentation::Null => Value::null(),
76 DIFValueRepresentation::String(str) => Value {
77 actual_type: Box::new(get_core_lib_type_definition(
78 CoreLibPointerId::Text,
79 )),
80 inner: CoreValue::Text(str.clone().into()),
81 },
82 DIFValueRepresentation::Boolean(b) => Value {
83 actual_type: Box::new(get_core_lib_type_definition(
84 CoreLibPointerId::Boolean,
85 )),
86 inner: CoreValue::Boolean((*b).into()),
87 },
88 DIFValueRepresentation::Number(n) => Value {
89 actual_type: Box::new(get_core_lib_type_definition(
90 CoreLibPointerId::Decimal(Some(DecimalTypeVariant::F64)),
91 )),
92 inner: CoreValue::TypedDecimal(TypedDecimal::F64(
93 OrderedFloat::from(*n),
94 )),
95 },
96 DIFValueRepresentation::Array(array) => Value {
97 actual_type: Box::new(get_core_lib_type_definition(
98 CoreLibPointerId::List,
99 )),
100 inner: CoreValue::List(
101 array
102 .iter()
103 .map(|v| v.to_value_container(memory))
104 .collect::<Result<Vec<ValueContainer>, _>>()?
105 .into(),
106 ),
107 },
108 DIFValueRepresentation::Object(object) => {
109 let mut map: Vec<(String, ValueContainer)> = Vec::new();
110 for (k, v) in object.clone() {
111 map.push((k, v.to_value_container(memory)?));
112 }
113 Value {
114 actual_type: Box::new(get_core_lib_type_definition(
115 CoreLibPointerId::Map,
116 )),
117 inner: CoreValue::Map(map.into()),
118 }
119 }
120 DIFValueRepresentation::Map(map) => {
121 let mut core_map = IndexMap::default();
122 for (k, v) in map {
123 core_map.insert(
124 k.to_value_container(memory)?,
125 v.to_value_container(memory)?,
126 );
127 }
128 Value {
129 actual_type: Box::new(get_core_lib_type_definition(
130 CoreLibPointerId::Map,
131 )),
132 inner: CoreValue::Map(core_map.into()),
133 }
134 }
135 _ => {
136 core::todo!(
137 "#388 Other DIFValueRepresentation variants not supported yet"
138 )
139 }
140 })
141 }
142
143 pub fn to_value_with_type(
146 &self,
147 type_definition: &DIFTypeDefinition,
148 memory: &RefCell<Memory>,
149 ) -> Result<Value, DIFReferenceNotFoundError> {
150 let val = match type_definition {
151 DIFTypeDefinition::Reference(r) => {
152 if let Ok(core_lib_ptr_id) = CoreLibPointerId::try_from(r) {
153 match core_lib_ptr_id {
154 CoreLibPointerId::Map
157 if let DIFValueRepresentation::Object(object) =
158 self =>
159 {
160 let mut entries: Vec<(String, ValueContainer)> =
161 Vec::new();
162 for (k, v) in object.clone().into_iter() {
163 entries
164 .push((k, v.to_value_container(memory)?));
165 }
166 Some(Value::from(CoreValue::Map(Map::from(
167 entries,
168 ))))
169 }
170 CoreLibPointerId::Map
172 if let DIFValueRepresentation::Array(array) =
173 self =>
174 {
175 if !array.is_empty() {
177 unreachable!(
178 "Invalid DIF value, non-empty array with map type"
179 )
180 }
181 Some(Value::from(CoreValue::Map(Map::Structural(
182 vec![],
183 ))))
184 }
185 CoreLibPointerId::Integer(None)
187 if let DIFValueRepresentation::String(s) = self =>
188 {
189 Some(Value::from(CoreValue::Integer(
190 Integer::from_string(s).unwrap(),
191 )))
192 }
193 CoreLibPointerId::Integer(Some(variant))
194 if let DIFValueRepresentation::String(s) = self =>
195 {
196 Some(Value::from(CoreValue::TypedInteger(
197 TypedInteger::from_string_with_variant(
198 s, variant,
199 )
200 .unwrap(),
201 )))
202 }
203 _ => None,
205 }
206 } else {
207 core::todo!("#389 Handle non-core library type references")
208 }
209 }
210 _ => None,
211 };
212 let val = match val {
213 Some(v) => v,
214 None => self.to_default_value(memory)?,
215 };
216
217 let ty = type_definition.to_type_definition(memory);
218
219 Ok(Value {
220 actual_type: Box::new(ty),
221 ..val
222 })
223 }
224}
225
226#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
227#[serde(untagged)]
228pub enum DeserializeMapOrArray<T> {
229 MapEntry(T, T),
230 ArrayEntry(T),
231}
232
233impl DIFTypeRepresentation {
234 pub fn from_structural_type_definition(
235 struct_def: &StructuralTypeDefinition,
236 memory: &RefCell<Memory>,
237 ) -> Self {
238 match struct_def {
239 StructuralTypeDefinition::Null => DIFTypeRepresentation::Null,
240 StructuralTypeDefinition::Boolean(b) => {
241 DIFTypeRepresentation::Boolean(b.as_bool())
242 }
243 StructuralTypeDefinition::Integer(i) => {
244 DIFTypeRepresentation::Number(i.as_i128().unwrap() as f64)
246 }
247 StructuralTypeDefinition::TypedInteger(i) => {
248 DIFTypeRepresentation::Number(i.as_i128().unwrap() as f64)
249 }
250 StructuralTypeDefinition::Range((start, end)) => {
251 DIFTypeRepresentation::Array(vec![
252 DIFType::from_type(start, memory),
253 DIFType::from_type(end, memory),
254 ])
255 }
256 StructuralTypeDefinition::Decimal(d) => {
257 DIFTypeRepresentation::Number(d.into_f64())
258 }
259 StructuralTypeDefinition::TypedDecimal(d) => {
260 DIFTypeRepresentation::Number(d.as_f64())
261 }
262 StructuralTypeDefinition::Text(t) => {
263 DIFTypeRepresentation::String(t.0.clone())
264 }
265 StructuralTypeDefinition::Endpoint(endpoint) => {
266 DIFTypeRepresentation::String(endpoint.to_string())
267 }
268 StructuralTypeDefinition::List(arr) => {
269 DIFTypeRepresentation::Array(
270 arr.iter().map(|v| DIFType::from_type(v, memory)).collect(),
271 )
272 }
273 StructuralTypeDefinition::Map(fields) => {
274 DIFTypeRepresentation::Map(
275 fields
276 .iter()
277 .map(|(k, v)| {
278 (
279 DIFType::from_type(k, memory),
280 DIFType::from_type(v, memory),
281 )
282 })
283 .collect(),
284 )
285 }
286 }
287 }
288}
289
290impl Serialize for DIFValueRepresentation {
291 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
292 where
293 S: Serializer,
294 {
295 match self {
296 DIFValueRepresentation::Null => serializer.serialize_unit(),
297 DIFValueRepresentation::Boolean(b) => serializer.serialize_bool(*b),
298 DIFValueRepresentation::String(s) => serializer.serialize_str(s),
299 DIFValueRepresentation::Number(f) => serializer.serialize_f64(*f),
300 DIFValueRepresentation::Array(vec) => vec.serialize(serializer),
301 DIFValueRepresentation::Map(entries) => {
302 let mut seq = serializer.serialize_seq(Some(entries.len()))?;
303 for (k, v) in entries {
304 seq.serialize_element(&vec![k, v])?;
305 }
306 seq.end()
307 }
308 DIFValueRepresentation::Object(fields) => {
309 let mut map = serializer.serialize_map(Some(fields.len()))?;
310 for (k, v) in fields {
311 map.serialize_entry(k, v)?;
312 }
313 map.end()
314 }
315 }
316 }
317}
318
319impl<'de> Deserialize<'de> for DIFValueRepresentation {
320 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
321 where
322 D: Deserializer<'de>,
323 {
324 struct DIFCoreValueVisitor;
325
326 impl<'de> Visitor<'de> for DIFCoreValueVisitor {
327 type Value = DIFValueRepresentation;
328
329 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
330 formatter.write_str("a valid DIFCoreValue")
331 }
332
333 fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E> {
334 Ok(DIFValueRepresentation::Boolean(value))
335 }
336
337 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E> {
338 Ok(DIFValueRepresentation::Number(value as f64))
339 }
340
341 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E> {
342 Ok(DIFValueRepresentation::Number(value as f64))
344 }
345
346 fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E> {
347 Ok(DIFValueRepresentation::Number(value))
348 }
349
350 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
351 where
352 E: de::Error,
353 {
354 Ok(DIFValueRepresentation::String(value.to_string()))
355 }
356
357 fn visit_string<E>(self, value: String) -> Result<Self::Value, E> {
358 Ok(DIFValueRepresentation::String(value))
359 }
360
361 fn visit_none<E>(self) -> Result<Self::Value, E> {
362 Ok(DIFValueRepresentation::Null)
363 }
364
365 fn visit_unit<E>(self) -> Result<Self::Value, E> {
366 Ok(DIFValueRepresentation::Null)
367 }
368
369 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
371 where
372 A: SeqAccess<'de>,
373 {
374 let first_entry = seq
375 .next_element::<DeserializeMapOrArray<DIFValueContainer>>(
376 )?;
377 match first_entry {
378 Some(DeserializeMapOrArray::ArrayEntry(first)) => {
379 let mut elements = vec![first];
380 while let Some(elem) =
381 seq.next_element::<DIFValueContainer>()?
382 {
383 elements.push(elem);
384 }
385 Ok(DIFValueRepresentation::Array(elements))
386 }
387 Some(DeserializeMapOrArray::MapEntry(k, v)) => {
388 let mut elements = vec![(k, v)];
389 while let Some((k, v)) = seq.next_element::<(
390 DIFValueContainer,
391 DIFValueContainer,
392 )>(
393 )? {
394 elements.push((k, v));
395 }
396 Ok(DIFValueRepresentation::Map(elements))
397 }
398 None => Ok(DIFValueRepresentation::Array(vec![])), }
400 }
401
402 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
404 where
405 A: MapAccess<'de>,
406 {
407 let mut entries = Vec::new();
408 while let Some((k, v)) = map.next_entry()? {
409 entries.push((k, v));
410 }
411 Ok(DIFValueRepresentation::Object(entries))
412 }
413 }
414
415 deserializer.deserialize_any(DIFCoreValueVisitor)
416 }
417}
418
419impl Serialize for DIFTypeRepresentation {
420 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
421 where
422 S: Serializer,
423 {
424 match self {
425 DIFTypeRepresentation::Null => serializer.serialize_unit(),
426 DIFTypeRepresentation::Boolean(b) => serializer.serialize_bool(*b),
427 DIFTypeRepresentation::String(s) => serializer.serialize_str(s),
428 DIFTypeRepresentation::Number(f) => serializer.serialize_f64(*f),
429 DIFTypeRepresentation::Array(vec) => vec.serialize(serializer),
430 DIFTypeRepresentation::Map(entries) => {
431 let mut seq = serializer.serialize_seq(Some(entries.len()))?;
432 for (k, v) in entries {
433 seq.serialize_element(&vec![k, v])?;
434 }
435 seq.end()
436 }
437 DIFTypeRepresentation::Object(fields) => {
438 let mut map = serializer.serialize_map(Some(fields.len()))?;
439 for (k, v) in fields {
440 map.serialize_entry(k, v)?;
441 }
442 map.end()
443 }
444 }
445 }
446}
447
448impl<'de> Deserialize<'de> for DIFTypeRepresentation {
449 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
450 where
451 D: Deserializer<'de>,
452 {
453 struct DIFCoreValueVisitor;
454
455 impl<'de> Visitor<'de> for DIFCoreValueVisitor {
456 type Value = DIFTypeRepresentation;
457
458 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
459 formatter.write_str("a valid DIFCoreValue")
460 }
461
462 fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E> {
463 Ok(DIFTypeRepresentation::Boolean(value))
464 }
465
466 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E> {
467 Ok(DIFTypeRepresentation::Number(value as f64))
468 }
469
470 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E> {
471 Ok(DIFTypeRepresentation::Number(value as f64))
473 }
474
475 fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E> {
476 Ok(DIFTypeRepresentation::Number(value))
477 }
478
479 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
480 where
481 E: de::Error,
482 {
483 Ok(DIFTypeRepresentation::String(value.to_string()))
484 }
485
486 fn visit_string<E>(self, value: String) -> Result<Self::Value, E> {
487 Ok(DIFTypeRepresentation::String(value))
488 }
489
490 fn visit_none<E>(self) -> Result<Self::Value, E> {
491 Ok(DIFTypeRepresentation::Null)
492 }
493
494 fn visit_unit<E>(self) -> Result<Self::Value, E> {
495 Ok(DIFTypeRepresentation::Null)
496 }
497
498 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
500 where
501 A: SeqAccess<'de>,
502 {
503 let first_entry =
504 seq.next_element::<DeserializeMapOrArray<DIFType>>()?;
505 match first_entry {
506 Some(DeserializeMapOrArray::ArrayEntry(first)) => {
507 let mut elements = vec![first];
508 while let Some(elem) = seq.next_element::<DIFType>()? {
509 elements.push(elem);
510 }
511 Ok(DIFTypeRepresentation::Array(elements))
512 }
513 Some(DeserializeMapOrArray::MapEntry(k, v)) => {
514 let mut elements = vec![(k, v)];
515 while let Some((k, v)) =
516 seq.next_element::<(DIFType, DIFType)>()?
517 {
518 elements.push((k, v));
519 }
520 Ok(DIFTypeRepresentation::Map(elements))
521 }
522 None => Ok(DIFTypeRepresentation::Array(vec![])), }
524 }
525
526 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
528 where
529 A: MapAccess<'de>,
530 {
531 let mut entries = Vec::new();
532 while let Some((k, v)) = map.next_entry()? {
533 entries.push((k, v));
534 }
535 Ok(DIFTypeRepresentation::Object(entries))
536 }
537 }
538
539 deserializer.deserialize_any(DIFCoreValueVisitor)
540 }
541}