Skip to main content

datex_core/serde/
serializer.rs

1use crate::{
2    core_compiler::value_compiler::compile_value_container,
3    runtime::execution::{ExecutionInput, ExecutionOptions, execute_dxb_sync},
4    serde::error::SerializationError,
5    values::{
6        core_value::CoreValue,
7        core_values::{list::List, map::Map},
8        value_container::ValueContainer,
9    },
10};
11use core::result::Result;
12use serde::ser::{
13    Serialize, SerializeMap, SerializeSeq, SerializeStruct,
14    SerializeStructVariant, SerializeTuple, SerializeTupleStruct,
15    SerializeTupleVariant, Serializer,
16};
17
18use crate::prelude::*;
19pub struct DatexSerializer {}
20
21impl Default for DatexSerializer {
22    fn default() -> Self {
23        Self::new()
24    }
25}
26
27impl DatexSerializer {
28    pub fn new() -> Self {
29        DatexSerializer {}
30    }
31}
32
33pub fn to_bytes<T>(value: &T) -> Result<Vec<u8>, SerializationError>
34where
35    T: Serialize,
36{
37    let value_container = to_value_container(value)?;
38    Ok(compile_value_container(&value_container))
39}
40pub fn to_value_container<T>(
41    value: &T,
42) -> Result<ValueContainer, SerializationError>
43where
44    T: Serialize,
45{
46    let mut serializer = DatexSerializer::new();
47    let container = value.serialize(&mut serializer)?;
48    Ok(container)
49}
50
51/// Serializer for structs
52/// For example:
53/// struct MyStruct {
54///     field1: String,
55///     field2: i32,
56/// }
57/// will be serialized as:
58/// {"field1": String, "field2": i32}
59#[derive(Default)]
60pub struct StructSerializer {
61    fields: Vec<(String, ValueContainer)>,
62}
63impl StructSerializer {
64    pub fn new() -> Self {
65        Self::default()
66    }
67}
68impl SerializeStruct for StructSerializer {
69    type Ok = ValueContainer;
70    type Error = SerializationError;
71
72    fn serialize_field<T: ?Sized>(
73        &mut self,
74        key: &'static str,
75        value: &T,
76    ) -> Result<(), Self::Error>
77    where
78        T: serde::Serialize,
79    {
80        let vc = value.serialize(&mut DatexSerializer::new())?;
81        self.fields.push((key.to_string(), vc));
82        Ok(())
83    }
84
85    fn end(self) -> Result<Self::Ok, Self::Error> {
86        Ok(Map::StructuralWithStringKeys(self.fields).into())
87    }
88}
89
90/// Serializer for tuples
91/// For example:
92/// (i32, String)
93/// will be serialized as:
94/// [i32, String]
95#[derive(Default)]
96pub struct TupleSerializer {
97    elements: Vec<ValueContainer>,
98}
99impl TupleSerializer {
100    pub fn new() -> Self {
101        Self {
102            elements: Vec::new(),
103        }
104    }
105}
106impl SerializeTuple for TupleSerializer {
107    type Ok = ValueContainer;
108    type Error = SerializationError;
109
110    fn serialize_element<T: ?Sized>(
111        &mut self,
112        value: &T,
113    ) -> Result<(), Self::Error>
114    where
115        T: serde::Serialize,
116    {
117        let vc = value.serialize(&mut DatexSerializer::new())?;
118        self.elements.push(vc);
119        Ok(())
120    }
121
122    fn end(self) -> Result<Self::Ok, Self::Error> {
123        let mut list = List::default();
124        for element in self.elements.into_iter() {
125            list.push(element);
126        }
127        Ok(ValueContainer::from(CoreValue::List(list)))
128    }
129}
130
131/// Serializer for tuple structs
132/// For example:
133/// struct MyStruct(i32, String);
134/// will be serialized as:
135/// [i32, String]
136pub struct TupleStructSerializer {
137    _name: &'static str,
138    fields: List,
139}
140impl TupleStructSerializer {
141    pub fn new(name: &'static str) -> Self {
142        Self {
143            _name: name,
144            fields: List::default(),
145        }
146    }
147}
148impl SerializeTupleStruct for TupleStructSerializer {
149    type Ok = ValueContainer;
150    type Error = SerializationError;
151
152    fn serialize_field<T: ?Sized>(
153        &mut self,
154        value: &T,
155    ) -> Result<(), Self::Error>
156    where
157        T: Serialize,
158    {
159        let field = value.serialize(&mut DatexSerializer::new())?;
160        self.fields.push(field);
161        Ok(())
162    }
163
164    fn end(self) -> Result<Self::Ok, Self::Error> {
165        Ok(ValueContainer::from(self.fields))
166    }
167}
168
169/// Serializer for enum variants with tuple fields
170/// For example:
171/// enum MyEnum {
172///     Variant1(i32, String),
173///     Variant2(bool),
174/// }
175/// will be serialized as:
176/// {"Variant1": [i32, String]}
177pub struct TupleVariantSerializer {
178    variant: &'static str,
179    fields: List,
180}
181impl TupleVariantSerializer {
182    pub fn new(variant: &'static str) -> Self {
183        Self {
184            variant,
185            fields: List::default(),
186        }
187    }
188}
189impl SerializeTupleVariant for TupleVariantSerializer {
190    type Ok = ValueContainer;
191    type Error = SerializationError;
192
193    fn serialize_field<T: ?Sized>(
194        &mut self,
195        value: &T,
196    ) -> Result<(), Self::Error>
197    where
198        T: Serialize,
199    {
200        let field = value.serialize(&mut DatexSerializer::new())?;
201        self.fields.push(field);
202        Ok(())
203    }
204
205    fn end(self) -> Result<Self::Ok, Self::Error> {
206        Ok(ValueContainer::from(CoreValue::Map(Map::from(vec![(
207            self.variant.to_string(),
208            self.fields.into(),
209        )]))))
210    }
211}
212
213/// Serializer for enum variants with struct fields
214/// For example:
215/// enum MyEnum {
216///     Variant1 { x: i32, y: String },
217///     Variant2 { a: bool },
218/// }
219/// will be serialized as:
220/// {"Variant1": {"x": i32, "y": String}}
221pub struct StructVariantSerializer {
222    variant: &'static str,
223    fields: Vec<(String, ValueContainer)>,
224}
225impl StructVariantSerializer {
226    pub fn new(variant: &'static str) -> Self {
227        Self {
228            variant,
229            fields: Vec::new(),
230        }
231    }
232}
233impl SerializeStructVariant for StructVariantSerializer {
234    type Ok = ValueContainer;
235    type Error = SerializationError;
236
237    fn serialize_field<T: ?Sized>(
238        &mut self,
239        key: &'static str,
240        value: &T,
241    ) -> Result<(), Self::Error>
242    where
243        T: serde::Serialize,
244    {
245        let field = value.serialize(&mut DatexSerializer::new())?;
246        self.fields.push((key.to_string(), field));
247        Ok(())
248    }
249
250    fn end(self) -> Result<Self::Ok, Self::Error> {
251        Ok(Map::from(vec![(
252            self.variant.to_string(),
253            Map::from(self.fields).into(),
254        )])
255        .into())
256    }
257}
258
259/// Serializer for sequences
260/// For example:
261/// vec![1, 2, 3]
262/// will be serialized as:
263/// [1, 2, 3]
264#[derive(Default)]
265pub struct SeqSerializer {
266    elements: List,
267}
268impl SeqSerializer {
269    pub fn new() -> Self {
270        Self {
271            elements: List::default(),
272        }
273    }
274}
275impl SerializeSeq for SeqSerializer {
276    type Ok = ValueContainer;
277    type Error = SerializationError;
278
279    fn serialize_element<T: ?Sized>(
280        &mut self,
281        value: &T,
282    ) -> Result<(), Self::Error>
283    where
284        T: serde::Serialize,
285    {
286        let vc = value.serialize(&mut DatexSerializer::new())?;
287        self.elements.push(vc);
288        Ok(())
289    }
290
291    fn end(self) -> Result<Self::Ok, Self::Error> {
292        Ok(ValueContainer::from(self.elements))
293    }
294}
295
296/// Serializer for maps
297/// For example:
298///     HashMap<String, i32>
299/// will be serialized as:
300///     {"key": 1, "key2": 2, "key3": 3}
301#[derive(Default)]
302pub struct MapSerializer {
303    entries: Vec<(ValueContainer, Option<ValueContainer>)>,
304}
305impl MapSerializer {
306    pub fn new() -> Self {
307        Self {
308            entries: Vec::new(),
309        }
310    }
311}
312
313impl SerializeMap for MapSerializer {
314    type Ok = ValueContainer;
315    type Error = SerializationError;
316
317    fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error>
318    where
319        T: serde::Serialize,
320    {
321        let key = key.serialize(&mut DatexSerializer::new())?;
322        self.entries.push((key, None));
323        Ok(())
324    }
325
326    fn serialize_value<T: ?Sized>(
327        &mut self,
328        value: &T,
329    ) -> Result<(), Self::Error>
330    where
331        T: serde::Serialize,
332    {
333        let vc = value.serialize(&mut DatexSerializer::new())?;
334        if let Some(last) = self.entries.last_mut() {
335            last.1 = Some(vc);
336            Ok(())
337        } else {
338            Err(SerializationError::Custom(
339                "serialize_value called before serialize_key".to_string(),
340            ))
341        }
342    }
343
344    fn end(self) -> Result<Self::Ok, Self::Error> {
345        let mut map = Map::default();
346        for (key, value) in self.entries.into_iter() {
347            if let Some(value) = value {
348                map.set(&key, value);
349            } else {
350                return Err(SerializationError::Custom(
351                    "Map entry without value".to_string(),
352                ));
353            }
354        }
355        Ok(map.into())
356    }
357}
358
359/// Main serializer implementation
360impl Serializer for &mut DatexSerializer {
361    type Ok = ValueContainer;
362    type Error = SerializationError;
363
364    type SerializeStruct = StructSerializer;
365    type SerializeTuple = TupleSerializer;
366    type SerializeTupleStruct = TupleStructSerializer;
367    type SerializeTupleVariant = TupleVariantSerializer;
368    type SerializeStructVariant = StructVariantSerializer;
369    type SerializeSeq = SeqSerializer;
370    type SerializeMap = MapSerializer;
371
372    fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
373        Ok(ValueContainer::from(v))
374    }
375
376    fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
377        Ok(ValueContainer::from(v))
378    }
379
380    fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
381        Ok(ValueContainer::from(v))
382    }
383
384    fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
385        Ok(ValueContainer::from(v))
386    }
387
388    fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
389        Ok(ValueContainer::from(v))
390    }
391
392    fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
393        Ok(ValueContainer::from(v))
394    }
395
396    fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
397        Ok(ValueContainer::from(v))
398    }
399
400    fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
401        Ok(ValueContainer::from(v))
402    }
403
404    fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
405        Ok(ValueContainer::from(v))
406    }
407
408    fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
409        Ok(ValueContainer::from(v))
410    }
411
412    fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
413        Ok(ValueContainer::from(v))
414    }
415
416    fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
417        Ok(ValueContainer::from(v))
418    }
419
420    fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
421        Ok(ValueContainer::from(v))
422    }
423
424    fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
425        Ok(ValueContainer::from(v.to_string()))
426    }
427
428    fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
429        Ok(ValueContainer::from(v))
430    }
431
432    fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
433        core::todo!("#134 Undescribed by author.")
434    }
435
436    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
437        Ok(CoreValue::Null.into())
438    }
439
440    fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
441    where
442        T: ?Sized + serde::Serialize,
443    {
444        value.serialize(&mut *self).map_err(|e| {
445            SerializationError::CanNotSerialize(format!(
446                "Failed to serialize Some value: {e}"
447            ))
448        })
449    }
450
451    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
452        Ok(Map::default().into())
453    }
454
455    fn serialize_struct(
456        self,
457        _name: &'static str,
458        _len: usize,
459    ) -> Result<Self::SerializeStruct, Self::Error> {
460        Ok(StructSerializer::new())
461    }
462
463    fn serialize_unit_struct(
464        self,
465        _name: &'static str,
466    ) -> Result<Self::Ok, Self::Error> {
467        Ok(Map::default().into())
468    }
469
470    fn serialize_unit_variant(
471        self,
472        _name: &'static str,
473        _variant_index: u32,
474        variant: &'static str,
475    ) -> Result<Self::Ok, Self::Error> {
476        Ok(ValueContainer::from(variant))
477    }
478
479    fn serialize_newtype_struct<T>(
480        self,
481        name: &'static str,
482        value: &T,
483    ) -> Result<Self::Ok, Self::Error>
484    where
485        T: ?Sized + serde::Serialize,
486    {
487        if name == "datex::endpoint" {
488            let endpoint = value
489                .serialize(&mut *self)?
490                .to_value()
491                .borrow()
492                .cast_to_endpoint()
493                .unwrap();
494            Ok(ValueContainer::from(endpoint))
495        } else if name == "datex::value" {
496            // unsafe cast value to ValueContainer
497            let bytes = unsafe { &*(value as *const T as *const Vec<u8>) };
498            Ok(execute_dxb_sync(ExecutionInput::new(
499                bytes,
500                ExecutionOptions::default(),
501                None,
502            ))
503            .unwrap()
504            .unwrap())
505        } else if name.starts_with("datex::") {
506            // Serialize internal new type structs as normal structs
507            // {"datex::field": value}
508            // instead of
509            // value
510            let mut struct_serializer = StructSerializer::new();
511            struct_serializer.serialize_field(name, value)?;
512            struct_serializer.end()
513        } else {
514            Ok(value.serialize(&mut *self)?)
515        }
516    }
517
518    /// Serialize newtype enum variants as structs with one field
519    /// For example:
520    /// enum MyEnum {
521    ///     Variant1(String),
522    ///     Variant2(i32, String),
523    /// }
524    /// is serialized as
525    /// {"Variant2": [100, "hello"]}
526    fn serialize_newtype_variant<T>(
527        self,
528        _name: &'static str,
529        _variant_index: u32,
530        variant: &'static str,
531        value: &T,
532    ) -> Result<Self::Ok, Self::Error>
533    where
534        T: ?Sized + serde::Serialize,
535    {
536        let field = value.serialize(&mut *self)?;
537        Ok(ValueContainer::from(CoreValue::Map(Map::from(vec![(
538            variant.to_string(),
539            field,
540        )]))))
541    }
542
543    fn serialize_seq(
544        self,
545        _len: Option<usize>,
546    ) -> Result<Self::SerializeSeq, Self::Error> {
547        Ok(SeqSerializer::new())
548    }
549
550    fn serialize_tuple(
551        self,
552        _len: usize,
553    ) -> Result<Self::SerializeTuple, Self::Error> {
554        Ok(TupleSerializer::new())
555    }
556
557    fn serialize_tuple_struct(
558        self,
559        name: &'static str,
560        _len: usize,
561    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
562        Ok(TupleStructSerializer::new(name))
563    }
564
565    fn serialize_tuple_variant(
566        self,
567        _name: &'static str,
568        _variant_index: u32,
569        variant: &'static str,
570        _len: usize,
571    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
572        Ok(TupleVariantSerializer::new(variant))
573    }
574
575    fn serialize_map(
576        self,
577        _len: Option<usize>,
578    ) -> Result<Self::SerializeMap, Self::Error> {
579        Ok(MapSerializer::new())
580    }
581
582    fn serialize_struct_variant(
583        self,
584        _name: &'static str,
585        _variant_index: u32,
586        variant: &'static str,
587        _len: usize,
588    ) -> Result<Self::SerializeStructVariant, Self::Error> {
589        Ok(StructVariantSerializer::new(variant))
590    }
591
592    fn is_human_readable(&self) -> bool {
593        true
594    }
595}
596
597#[cfg(test)]
598mod tests {
599    use crate::{
600        assert_structural_eq,
601        serde::serializer::{DatexSerializer, to_bytes, to_value_container},
602        traits::structural_eq::StructuralEq,
603        values::core_values::{endpoint::Endpoint, map::Map},
604    };
605
606    use crate::{
607        prelude::*,
608        values::{
609            core_value::CoreValue, value::Value,
610            value_container::ValueContainer,
611        },
612    };
613    use core::assert_matches;
614    use serde::{Deserialize, Serialize};
615
616    #[derive(Serialize)]
617    struct TestStruct {
618        field1: String,
619        field2: i32,
620    }
621
622    #[derive(Serialize)]
623    struct TestTupleStruct(String, i32);
624
625    #[derive(Serialize)]
626    struct UnitStruct;
627
628    #[derive(Serialize)]
629    enum TestEnum {
630        Unit,
631        Tuple(i32, String),
632        Struct { x: bool, y: f64 },
633    }
634
635    #[derive(Serialize)]
636    struct NestedStruct {
637        nested: TestStruct,
638        value: i32,
639    }
640
641    #[derive(Serialize)]
642    struct StructWithOption {
643        value: Option<i32>,
644    }
645
646    #[derive(Serialize)]
647    struct StructWithVec {
648        values: Vec<i32>,
649    }
650
651    #[derive(Serialize)]
652    struct TestStructWithEndpoint {
653        endpoint: Endpoint,
654    }
655
656    #[derive(Serialize, Deserialize, Debug)]
657    pub struct StructWithUSize {
658        pub usize: Option<usize>,
659    }
660
661    #[test]
662    fn datex_serializer() {
663        let mut serializer = DatexSerializer::new();
664        let test_struct = TestStruct {
665            field1: "Hello".to_string(),
666            field2: 42,
667        };
668        let value_container = test_struct.serialize(&mut serializer).unwrap();
669        assert_matches!(
670            value_container,
671            ValueContainer::Value(Value {
672                inner: CoreValue::Map(_),
673                ..
674            })
675        );
676    }
677
678    #[test]
679    fn r#struct() {
680        let test_struct = TestStruct {
681            field1: "Hello".to_string(),
682            field2: 42,
683        };
684        let result = to_value_container(&test_struct).unwrap();
685        assert_eq!(result.to_string(), r#"{"field1": "Hello", "field2": 42}"#);
686    }
687
688    #[test]
689    fn tuple_struct() {
690        let ts = TestTupleStruct("hi".to_string(), 99);
691        let result = to_value_container(&ts).unwrap();
692        assert_eq!(result.to_string(), r#"["hi", 99]"#);
693    }
694
695    #[test]
696    fn unit_struct() {
697        let us = UnitStruct;
698        let result = to_value_container(&us).unwrap();
699        assert_eq!(result.to_string(), r#"{}"#);
700    }
701
702    #[test]
703    fn enum_unit_variant() {
704        let e = TestEnum::Unit;
705        let result = to_value_container(&e).unwrap();
706        assert_eq!(result.to_string(), r#""Unit""#);
707    }
708
709    #[test]
710    fn enum_tuple_variant() {
711        let e = TestEnum::Tuple(42, "hello".to_string());
712        let result = to_value_container(&e).unwrap();
713        assert_eq!(result.to_string(), r#"{"Tuple": [42, "hello"]}"#);
714    }
715
716    #[test]
717    fn enum_struct_variant() {
718        let e = TestEnum::Struct { x: true, y: 3.5 };
719        let result = to_value_container(&e).unwrap();
720        assert_eq!(result.to_string(), r#"{"Struct": {"x": true, "y": 3.5}}"#);
721    }
722
723    #[test]
724    fn vec() {
725        let data = vec![10, 20, 30];
726        let result = to_value_container(&data).unwrap();
727        assert_eq!(result.to_string(), "[10, 20, 30]");
728    }
729
730    #[test]
731    fn tuple_array() {
732        let data = [1, 2, 3, 4];
733        let result = to_value_container(&data).unwrap();
734        assert_eq!(result.to_string(), "[1, 2, 3, 4]");
735    }
736
737    #[test]
738    fn nested_struct() {
739        let nested = NestedStruct {
740            nested: TestStruct {
741                field1: "A".to_string(),
742                field2: 1,
743            },
744            value: 99,
745        };
746        let result = to_value_container(&nested).unwrap();
747        assert_eq!(
748            result.to_string(),
749            r#"{"nested": {"field1": "A", "field2": 1}, "value": 99}"#
750        );
751    }
752
753    #[test]
754    fn struct_with_option_some() {
755        let s = StructWithOption { value: Some(42) };
756        let result = to_value_container(&s).unwrap();
757        assert_eq!(result.to_string(), r#"{"value": 42}"#);
758    }
759
760    #[test]
761    fn struct_with_option_none() {
762        let s = StructWithOption { value: None };
763        let result = to_value_container(&s).unwrap();
764        // None can serialize as null
765        assert_eq!(result.to_string(), r#"{"value": null}"#);
766    }
767
768    #[test]
769    fn struct_with_vec() {
770        let s = StructWithVec {
771            values: vec![1, 2, 3],
772        };
773        let result = to_value_container(&s).unwrap();
774        assert_eq!(result.to_string(), r#"{"values": [1, 2, 3]}"#);
775    }
776
777    #[test]
778    fn primitive_values() {
779        // integer
780        let i = 42;
781        let vc = to_value_container(&i).unwrap();
782        assert_eq!(vc.to_string(), "42");
783
784        // float
785        let f = 3.4;
786        let vc = to_value_container(&f).unwrap();
787        assert_eq!(vc.to_string(), "3.4");
788
789        // boolean
790        let b = true;
791        let vc = to_value_container(&b).unwrap();
792        assert_eq!(vc.to_string(), "true");
793
794        // string
795        let s = "test";
796        let vc = to_value_container(&s).unwrap();
797        assert_eq!(vc.to_string(), r#""test""#);
798    }
799
800    #[test]
801    fn array_serialization() {
802        let arr = vec![1, 2, 3];
803        let vc = to_value_container(&arr).unwrap();
804        assert_eq!(vc.to_string(), "[1, 2, 3]");
805    }
806
807    #[test]
808    fn serializer_into_inner_map() {
809        let mut serializer = DatexSerializer::new();
810        let s = TestStruct {
811            field1: "Hello".to_string(),
812            field2: 42,
813        };
814        let value_container = s.serialize(&mut serializer).unwrap();
815        assert_matches!(
816            value_container,
817            ValueContainer::Value(Value {
818                inner: CoreValue::Map(_),
819                ..
820            })
821        );
822    }
823
824    #[test]
825    fn struct_to_bytes() {
826        let test_struct = TestStruct {
827            field1: "Hello".to_string(),
828            field2: 42,
829        };
830        let result = to_bytes(&test_struct);
831        assert!(result.is_ok());
832        assert!(!result.unwrap().is_empty());
833    }
834
835    #[test]
836    fn to_bytes_with_struct_with_usize() {
837        let test_struct = StructWithUSize { usize: Some(42) };
838        let result = to_value_container(&test_struct);
839        assert!(result.is_ok());
840        let result = result.unwrap();
841        assert_structural_eq!(
842            result
843                .to_value()
844                .borrow()
845                .cast_to_map()
846                .unwrap()
847                .get("usize")
848                .unwrap(),
849            ValueContainer::from(42)
850        );
851    }
852
853    #[test]
854    fn endpoint() {
855        let script = "@test";
856        let result = to_value_container(&script).unwrap();
857        assert_eq!(result.to_string(), "\"@test\"");
858
859        let test_struct = TestStructWithEndpoint {
860            endpoint: Endpoint::new("@test"),
861        };
862
863        let result = to_value_container(&test_struct);
864        assert!(result.is_ok());
865        let result = result.unwrap();
866        let map = Map::StructuralWithStringKeys(vec![(
867            "endpoint".to_string(),
868            ValueContainer::from(Endpoint::new("@test")),
869        )]);
870        assert_eq!(result, ValueContainer::from(map));
871    }
872
873    #[derive(Serialize)]
874    struct MyNewtype(i32);
875
876    #[test]
877    fn newtype_struct() {
878        let my_newtype = MyNewtype(100);
879        let result = to_value_container(&my_newtype).unwrap();
880        assert_eq!(result.to_string(), r#"100"#);
881    }
882
883    #[derive(Serialize)]
884    struct StructType(i32, String, bool);
885    #[test]
886    fn newtype_struct_multiple_fields() {
887        let s = StructType(1, "test".to_string(), true);
888        let result = to_value_container(&s).unwrap();
889        assert_eq!(result.to_string(), r#"[1, "test", true]"#);
890    }
891
892    #[derive(Serialize)]
893    enum MyTaggedEnum {
894        Variant1 { x: i32, y: String },
895        Variant2(i32, String),
896        Empty,
897    }
898
899    #[test]
900    fn tagged_enum() {
901        let e = MyTaggedEnum::Variant1 {
902            x: 42,
903            y: "test".to_string(),
904        };
905        let result = to_value_container(&e).unwrap();
906        assert_eq!(
907            result.to_string(),
908            r#"{"Variant1": {"x": 42, "y": "test"}}"#
909        );
910
911        let e = MyTaggedEnum::Variant2(100, "hello".to_string());
912        let result = to_value_container(&e).unwrap();
913        assert_eq!(result.to_string(), r#"{"Variant2": [100, "hello"]}"#);
914
915        let e = MyTaggedEnum::Empty;
916        let result = to_value_container(&e).unwrap();
917        assert_eq!(result.to_string(), r#""Empty""#);
918    }
919}