datex_core/dif/
representation.rs

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