datex_core/serde/
mod.rs

1use crate::core_compiler::value_compiler::compile_value_container;
2use crate::values::value_container::ValueContainer;
3use core::result::Result;
4use serde::Serialize;
5
6pub use serde::Deserialize;
7pub mod deserializer;
8pub mod error;
9pub mod serializer;
10
11impl Serialize for ValueContainer {
12    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
13    where
14        S: serde::Serializer,
15    {
16        serializer.serialize_newtype_struct(
17            "datex::value",
18            &compile_value_container(self),
19        )
20    }
21}
22
23#[cfg(test)]
24mod tests {
25    use crate::assert_structural_eq;
26    use crate::decompiler::DecompileOptions;
27    use crate::logger::init_logger_debug;
28    use crate::serde::{
29        deserializer::{from_bytes, from_value_container},
30        serializer::{to_bytes, to_value_container},
31    };
32    use crate::stdlib::collections::{HashMap, HashSet};
33    use crate::traits::structural_eq::StructuralEq;
34    use crate::values::value_container::ValueContainer;
35    use datex_core::decompiler::decompile_body;
36    use log::info;
37    use serde::{Deserialize, Serialize};
38
39    // Tuple Struct
40    #[derive(Deserialize, Serialize, Debug, PartialEq)]
41    struct TestTupleStruct(String, i32, bool);
42
43    #[test]
44    fn tuplestruct_serde_value_container() {
45        let original = TestTupleStruct("Hello".to_string(), 42, true);
46        let serialized = to_value_container(&original).unwrap();
47        let deserialized: TestTupleStruct =
48            from_value_container(serialized).unwrap();
49        assert_eq!(original, deserialized);
50    }
51
52    #[test]
53    fn tuplestruct_serde_bytes() {
54        let original = TestTupleStruct("Hello".to_string(), 42, true);
55        let serialized = to_bytes(&original).unwrap();
56        let deserialized: TestTupleStruct = from_bytes(&serialized).unwrap();
57        assert_eq!(original, deserialized);
58    }
59
60    // Struct
61    #[derive(Deserialize, Serialize, Debug, PartialEq)]
62    struct TestStruct {
63        field1: String,
64        field2: i32,
65    }
66
67    #[test]
68    fn struct_serde_value_container() {
69        let original = TestStruct {
70            field1: "Hello".to_string(),
71            field2: 42,
72        };
73        let serialized = to_value_container(&original).unwrap();
74        let deserialized: TestStruct =
75            from_value_container(serialized).unwrap();
76        assert_eq!(original, deserialized);
77    }
78
79    #[test]
80    fn struct_serde_bytes() {
81        let data = to_bytes(&TestStruct {
82            field1: "Hello".to_string(),
83            field2: 42,
84        })
85        .unwrap();
86        let result: TestStruct = from_bytes(&data).unwrap();
87        assert_eq!(
88            result,
89            TestStruct {
90                field1: "Hello".to_string(),
91                field2: 42
92            }
93        );
94    }
95
96    // Nested Struct
97    #[derive(Deserialize, Serialize, Debug, PartialEq)]
98    struct NestedStruct {
99        nested_field: String,
100        test_struct: TestStruct,
101    }
102
103    #[test]
104    fn test_nested_struct_serde_value_container() {
105        let original = NestedStruct {
106            nested_field: "Nested".to_string(),
107            test_struct: TestStruct {
108                field1: "Hello".to_string(),
109                field2: 42,
110            },
111        };
112        let serialized = to_value_container(&original).unwrap();
113        let deserialized: NestedStruct =
114            from_value_container(serialized).unwrap();
115        assert_eq!(original, deserialized);
116    }
117
118    #[derive(Serialize, Deserialize, Debug, PartialOrd, PartialEq)]
119    pub struct StructWithUSize {
120        pub usize: Option<usize>,
121    }
122
123    #[derive(Serialize, Deserialize, Debug, PartialEq)]
124    pub struct StructWithValueContainer {
125        pub name: String,
126        pub value_container: ValueContainer,
127    }
128
129    #[test]
130    fn struct_with_option_serde_bytes() {
131        // struct with option
132        let val = StructWithUSize { usize: Some(42) };
133        let result = to_bytes(&val);
134        assert!(result.is_ok());
135        let deserialized: StructWithUSize =
136            from_bytes(&result.unwrap()).unwrap();
137        assert_eq!(val, deserialized);
138    }
139
140    // Core Value
141    #[test]
142    fn core_value_serde_bytes() {
143        // string
144        let val = "test string";
145        let result = to_bytes(&val);
146        assert!(result.is_ok());
147        let deserialized: String = from_bytes(&result.unwrap()).unwrap();
148        assert_eq!(val, deserialized);
149
150        // integer
151        let val = 42;
152        let result = to_bytes(&val);
153        assert!(result.is_ok());
154        let deserialized: i32 = from_bytes(&result.unwrap()).unwrap();
155        assert_eq!(val, deserialized);
156
157        // boolean
158        let val = true;
159        let result = to_bytes(&val);
160        assert!(result.is_ok());
161        let deserialized: bool = from_bytes(&result.unwrap()).unwrap();
162        assert_eq!(val, deserialized);
163
164        // option
165        let val: Option<()> = None;
166        let result = to_bytes(&val);
167        assert!(result.is_ok());
168        let deserialized: Option<()> = from_bytes(&result.unwrap()).unwrap();
169        assert_eq!(val, deserialized);
170
171        // vec
172        let val = vec![1, 2, 3];
173        let result = to_bytes(&val);
174        assert!(result.is_ok());
175        let deserialized: Vec<i32> = from_bytes(&result.unwrap()).unwrap();
176        assert_eq!(val, deserialized);
177
178        // tuple
179        let val = (1, "test".to_string(), true);
180        let result = to_bytes(&val);
181        assert!(result.is_ok());
182        let deserialized: (i32, String, bool) =
183            from_bytes(&result.unwrap()).unwrap();
184        assert_eq!(val, deserialized);
185    }
186
187    #[test]
188    fn struct_with_value_container_serde_bytes() {
189        init_logger_debug();
190        // struct with value container
191        let val = StructWithValueContainer {
192            name: "test".to_string(),
193            value_container: ValueContainer::from(vec![1, 2, 3]),
194        };
195        let result = to_bytes(&val).unwrap();
196        info!(
197            "{}",
198            decompile_body(&result, DecompileOptions::colorized()).unwrap()
199        );
200        let deserialized: StructWithValueContainer =
201            from_bytes(&result).unwrap();
202        assert_structural_eq!(
203            val.value_container,
204            deserialized.value_container
205        );
206    }
207
208    #[derive(Deserialize, Serialize, Debug, PartialEq)]
209    struct EmptyStruct;
210
211    #[test]
212    fn unit_struct_serde() {
213        let original = EmptyStruct;
214        let serialized = to_bytes(&original).unwrap();
215        let deserialized: EmptyStruct = from_bytes(&serialized).unwrap();
216        assert_eq!(original, deserialized);
217    }
218
219    #[derive(Deserialize, Serialize, Debug, PartialEq)]
220    struct EmptyTuple();
221
222    #[test]
223    fn empty_tuple_struct_serde() {
224        let original = EmptyTuple();
225        let serialized = to_bytes(&original).unwrap();
226        let deserialized: EmptyTuple = from_bytes(&serialized).unwrap();
227        assert_eq!(original, deserialized);
228    }
229
230    // Enum Variants
231    #[derive(Deserialize, Serialize, Debug, PartialEq)]
232    enum TestEnum {
233        Unit,
234        Tuple(i32, String),
235        Struct { x: bool, y: f64 },
236    }
237
238    #[test]
239    fn enum_variants_serde() {
240        let tuple = TestEnum::Tuple(42, "hello".to_string());
241        let unit = TestEnum::Unit;
242        let strukt = TestEnum::Struct { x: true, y: 3.5 };
243
244        for original in [unit, tuple, strukt] {
245            let serialized = to_bytes(&original).unwrap();
246            let deserialized: TestEnum = from_bytes(&serialized).unwrap();
247            assert_eq!(original, deserialized);
248        }
249    }
250
251    #[test]
252    fn empty_and_nested_collections_serde() {
253        // empty vec
254        let v: Vec<i32> = vec![];
255        let s = to_bytes(&v).unwrap();
256        let d: Vec<i32> = from_bytes(&s).unwrap();
257        assert_eq!(v, d);
258
259        // nested vec
260        let v = vec![vec![1, 2], vec![3, 4]];
261        let s = to_bytes(&v).unwrap();
262        let d: Vec<Vec<i32>> = from_bytes(&s).unwrap();
263        assert_eq!(v, d);
264
265        // hashmap
266        let mut map = HashMap::new();
267        map.insert("a".to_string(), 1);
268        map.insert("b".to_string(), 2);
269        let s = to_bytes(&map).unwrap();
270        let d: HashMap<String, i32> = from_bytes(&s).unwrap();
271        assert_eq!(map, d);
272
273        // hashset
274        let mut set = HashSet::new();
275        set.insert(1);
276        set.insert(2);
277        let s = to_bytes(&set).unwrap();
278        let d: HashSet<i32> = from_bytes(&s).unwrap();
279        assert_eq!(set, d);
280    }
281
282    #[test]
283    fn special_types_serde() {
284        // floats
285        let val = core::f64::consts::PI;
286        let s = to_bytes(&val).unwrap();
287        let d: f64 = from_bytes(&s).unwrap();
288        assert_eq!(val, d);
289
290        // char
291        let val = 'a';
292        let s = to_bytes(&val).unwrap();
293        let d: char = from_bytes(&s).unwrap();
294        assert_eq!(val, d);
295
296        // string with Unicode
297        let val = "こんにちは".to_string();
298        let s = to_bytes(&val).unwrap();
299        let d: String = from_bytes(&s).unwrap();
300        assert_eq!(val, d);
301    }
302
303    #[test]
304    fn error_handling_deserialize() {
305        // corrupted bytes
306        let bad_data = vec![0xFF, 0x00, 0xAB];
307        let result: Result<TestStruct, _> = from_bytes(&bad_data);
308        assert!(result.is_err());
309
310        // mismatched type
311        let original = TestStruct {
312            field1: "wrong".to_string(),
313            field2: 123,
314        };
315        let serialized = to_bytes(&original).unwrap();
316        let result: Result<NestedStruct, _> = from_bytes(&serialized);
317        assert!(result.is_err());
318    }
319
320    #[derive(Serialize, Deserialize, PartialEq, Debug)]
321    enum TestEnum2 {
322        Test(String),
323    }
324
325    #[test]
326    fn struct_enum_newtype() {
327        let e = TestEnum2::Test("hello".to_string());
328        let result = to_value_container(&e).unwrap();
329        assert_eq!(result.to_string(), r#"{"Test": "hello"}"#);
330        let back: TestEnum2 = from_value_container(result).unwrap();
331        assert_eq!(e, back);
332    }
333
334    #[derive(Serialize, Deserialize, PartialEq, Debug)]
335    #[serde(tag = "type", content = "content")]
336    enum TaggedEnum {
337        A { x: i32 },
338        B(String),
339    }
340
341    #[test]
342    fn enum_internal_tagged() {
343        let a = TaggedEnum::A { x: 1 };
344        let b = TaggedEnum::B("hello".into());
345
346        for val in [&a, &b] {
347            let bytes = to_bytes(val).unwrap();
348            let back: TaggedEnum = from_bytes(&bytes).unwrap();
349            assert_eq!(*val, back);
350        }
351    }
352
353    #[test]
354    fn float_special_values() {
355        for val in &[f64::NAN, f64::INFINITY, f64::NEG_INFINITY] {
356            let b = to_bytes(val).unwrap();
357            let back: f64 = from_bytes(&b).unwrap();
358            if val.is_nan() {
359                assert!(back.is_nan());
360            } else {
361                assert_eq!(*val, back);
362            }
363        }
364    }
365
366    #[derive(Serialize, Deserialize, PartialEq, Debug)]
367    struct Inner {
368        a: i32,
369        b: i32,
370    }
371
372    #[derive(Serialize, Deserialize, PartialEq, Debug)]
373    struct OuterFlatten {
374        x: String,
375        #[serde(flatten)]
376        inner: Inner,
377    }
378
379    #[test]
380    fn flatten_struct_fields() {
381        let val = OuterFlatten {
382            x: "X".to_string(),
383            inner: Inner { a: 1, b: 2 },
384        };
385        let b = to_bytes(&val).unwrap();
386        let d: OuterFlatten = from_bytes(&b).unwrap();
387        assert_eq!(val, d);
388    }
389
390    #[derive(Serialize, Deserialize, Debug, PartialEq)]
391    struct MyNewtype(i32);
392
393    #[test]
394    fn newtype_struct_serde() {
395        let val = MyNewtype(123);
396        let vc = to_value_container(&val).unwrap();
397        let deserialized: MyNewtype = from_value_container(vc.clone()).unwrap();
398        assert_eq!(val, deserialized);
399        assert_eq!(vc.to_string(), "123");
400    }
401
402    #[derive(Serialize, Deserialize, Debug, PartialEq)]
403    enum MyEnum {
404        Newtype(i32),
405        TupleVariant(i32, String),
406        StructVariant { x: bool },
407    }
408
409    #[test]
410    fn newtype_enum_variant_serde() {
411        let val = MyEnum::Newtype(99);
412        let vc = to_value_container(&val).unwrap();
413        let deserialized: MyEnum = from_value_container(vc.clone()).unwrap();
414        assert_eq!(val, deserialized);
415        assert_eq!(vc.to_string(), "{\"Newtype\": 99}");
416    }
417
418    #[derive(Serialize, Deserialize, Debug, PartialEq)]
419    struct StructWithEnum {
420        field: MyEnum,
421    }
422
423    #[test]
424    fn struct_with_enum_field() {
425        let val = StructWithEnum {
426            field: MyEnum::Newtype(42),
427        };
428        let vc = to_value_container(&val).unwrap();
429        let deserialized: StructWithEnum =
430            from_value_container(vc.clone()).unwrap();
431        assert_eq!(val, deserialized);
432    }
433
434    #[test]
435    fn nested_tuple_structs() {
436        #[derive(Serialize, Deserialize, Debug, PartialEq)]
437        struct InnerTuple(i32, String);
438
439        #[derive(Serialize, Deserialize, Debug, PartialEq)]
440        struct OuterTuple(InnerTuple, bool);
441
442        let val = OuterTuple(InnerTuple(10, "Hi".to_string()), true);
443        let vc = to_value_container(&val).unwrap();
444        let deserialized: OuterTuple =
445            from_value_container(vc.clone()).unwrap();
446        assert_eq!(val, deserialized);
447    }
448
449    #[test]
450    fn option_wrapped_types() {
451        let val: Option<String> = Some("hello".to_string());
452        let vc = to_value_container(&val).unwrap();
453        let deserialized: Option<String> =
454            from_value_container(vc.clone()).unwrap();
455        assert_eq!(val, deserialized);
456
457        let val: Option<i32> = None;
458        let vc = to_value_container(&val).unwrap();
459        let deserialized: Option<i32> =
460            from_value_container(vc.clone()).unwrap();
461        assert_eq!(val, deserialized);
462    }
463
464    #[test]
465    fn reference_and_str_types() {
466        let val: &str = "test_ref";
467        let vc = to_value_container(&val).unwrap();
468        let deserialized: String = from_value_container(vc.clone()).unwrap();
469        assert_eq!(val, deserialized);
470
471        let val: String = "owned_string".to_string();
472        let vc = to_value_container(&val).unwrap();
473        let deserialized: String = from_value_container(vc.clone()).unwrap();
474        assert_eq!(val, deserialized);
475    }
476
477    #[test]
478    fn array_and_tuple_arrays() {
479        let val = [1, 2, 3];
480        let vc = to_value_container(&val).unwrap();
481        let deserialized: [i32; 3] = from_value_container(vc.clone()).unwrap();
482        assert_eq!(val, deserialized);
483
484        let val = [(1, "a".to_string()), (2, "b".to_string())];
485        let vc = to_value_container(&val).unwrap();
486        let deserialized: [(i32, String); 2] =
487            from_value_container(vc.clone()).unwrap();
488        assert_eq!(val, deserialized);
489    }
490}