Skip to main content

datex_core/dif/
mod.rs

1use crate::prelude::*;
2use serde::{Deserialize, Serialize};
3
4pub mod interface;
5pub mod reference;
6pub mod representation;
7pub mod r#type;
8pub mod update;
9pub mod value;
10
11pub trait DIFConvertible: Serialize + for<'de> Deserialize<'de> {
12    fn to_json(self) -> String {
13        self.as_json()
14    }
15    fn to_json_pretty(self) -> String {
16        self.as_json_pretty()
17    }
18    fn from_json(json: &str) -> Self {
19        serde_json::from_str(json).unwrap()
20    }
21    fn as_json(&self) -> String {
22        serde_json::to_string(self).unwrap()
23    }
24    fn as_json_pretty(&self) -> String {
25        serde_json::to_string_pretty(self).unwrap()
26    }
27}
28
29#[cfg(test)]
30mod tests {
31    use crate::{
32        dif::{
33            DIFConvertible,
34            representation::DIFValueRepresentation,
35            r#type::{DIFType, DIFTypeDefinition},
36            update::DIFUpdateData,
37            value::{DIFValue, DIFValueContainer},
38        },
39        libs::core::CoreLibPointerId,
40        prelude::*,
41        runtime::memory::Memory,
42        types::definition::TypeDefinition,
43        values::{
44            core_value::CoreValue,
45            core_values::{
46                endpoint::Endpoint, integer::typed_integer::IntegerTypeVariant,
47                r#type::Type,
48            },
49            pointer::PointerAddress,
50            value::Value,
51            value_container::ValueContainer,
52        },
53    };
54    use alloc::string::ToString;
55    use core::cell::RefCell;
56
57    fn dif_value_circle(value_container: ValueContainer) -> DIFValueContainer {
58        let memory = RefCell::new(Memory::new(Endpoint::default()));
59        let dif_value_container: DIFValueContainer =
60            DIFValueContainer::from_value_container(&value_container, &memory);
61        let serialized = dif_value_container.as_json();
62        let deserialized: DIFValueContainer =
63            DIFValueContainer::from_json(&serialized);
64        assert_eq!(dif_value_container, deserialized);
65        dif_value_container
66    }
67
68    #[test]
69    fn serde() {
70        // replace
71        let dif_update =
72            DIFUpdateData::replace(DIFValueContainer::Value(DIFValue {
73                value: DIFValueRepresentation::String("Hello".to_string()),
74                ty: None,
75            }));
76        let serialized = dif_update.as_json();
77        let deserialized: DIFUpdateData = DIFUpdateData::from_json(&serialized);
78        assert_eq!(dif_update, deserialized);
79
80        // update property
81        let dif_update = DIFUpdateData::set(
82            "name",
83            DIFValueContainer::Value(DIFValue {
84                value: DIFValueRepresentation::Number(42.0),
85                ty: None,
86            }),
87        );
88        let serialized = dif_update.as_json();
89        let deserialized: DIFUpdateData = DIFUpdateData::from_json(&serialized);
90        assert_eq!(dif_update, deserialized);
91    }
92
93    #[test]
94    fn dif_value_serialization() {
95        let value = DIFValue {
96            value: DIFValueRepresentation::Null,
97            ty: Some(DIFTypeDefinition::Unit),
98        };
99        let serialized = value.as_json();
100        let deserialized = DIFValue::from_json(&serialized);
101        assert_eq!(value, deserialized);
102    }
103
104    #[test]
105    fn from_value_container_i32() {
106        let dif_value_container = dif_value_circle(ValueContainer::from(42i32));
107        if let DIFValueContainer::Value(dif_value) = &dif_value_container {
108            assert_eq!(dif_value.value, DIFValueRepresentation::Number(42f64));
109            assert_eq!(
110                dif_value.ty,
111                Some(DIFTypeDefinition::Reference(
112                    CoreLibPointerId::Integer(Some(IntegerTypeVariant::I32))
113                        .into()
114                ))
115            );
116        } else {
117            core::panic!("Expected DIFValueContainer::Value variant");
118        }
119    }
120
121    #[test]
122    fn from_value_container_text() {
123        let dif_value_container =
124            dif_value_circle(ValueContainer::from("Hello, World!"));
125        if let DIFValueContainer::Value(dif_value) = &dif_value_container {
126            assert_eq!(
127                dif_value.value,
128                DIFValueRepresentation::String("Hello, World!".to_string())
129            );
130            assert_eq!(dif_value.ty, None);
131        } else {
132            core::panic!("Expected DIFValueContainer::Value variant");
133        }
134    }
135
136    #[test]
137    fn dif_value_no_type() {
138        let val = ValueContainer::Value(Value::null());
139        let memory = RefCell::new(Memory::new(Endpoint::default()));
140        let dif_val = DIFValueContainer::from_value_container(&val, &memory);
141        assert_eq!(
142            dif_val,
143            DIFValueContainer::Value(DIFValue::new(
144                DIFValueRepresentation::Null,
145                Option::<DIFTypeDefinition>::None,
146            ),)
147        );
148    }
149
150    #[test]
151    fn dif_value_with_type() {
152        let val = ValueContainer::Value(Value {
153            inner: CoreValue::Null,
154            actual_type: Box::new(TypeDefinition::ImplType(
155                Box::new(Type::integer()),
156                vec![PointerAddress::Local([0, 0, 0, 0, 0])],
157            )),
158        });
159
160        let memory = RefCell::new(Memory::new(Endpoint::default()));
161        let dif_val = DIFValueContainer::from_value_container(&val, &memory);
162        assert_eq!(
163            dif_val,
164            DIFValueContainer::Value(DIFValue {
165                value: DIFValueRepresentation::Null,
166                ty: Some(DIFTypeDefinition::ImplType(
167                    Box::new(DIFType {
168                        name: None,
169                        mutability: None,
170                        type_definition: DIFTypeDefinition::Reference(
171                            PointerAddress::from(CoreLibPointerId::Integer(
172                                None
173                            ))
174                        )
175                    }),
176                    vec![PointerAddress::Local([0, 0, 0, 0, 0])]
177                ))
178            })
179        );
180    }
181}