Skip to main content

datex_core/serde/
mod.rs

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