vdf_serde_format/
serializer.rs

1use serde::{
2    ser::{self, SerializeSeq},
3    Serialize,
4};
5
6use crate::{
7    error::{Error, Result},
8    peek_expect_char, preprocess,
9    preprocessor::parse_string,
10};
11
12#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
13#[allow(dead_code)]
14enum LogLevel {
15    Error = 0,
16    Warn = 1,
17    Info = 2,
18    Debug = 3,
19    Trace = 4,
20}
21
22#[cfg(debug_assertions)]
23static mut INDENTATION: usize = 0;
24
25#[cfg(debug_assertions)]
26static mut CURRENT_LEVEL: LogLevel = LogLevel::Debug;
27macro_rules! log {
28    ($level:expr, $($arg:tt)*) => ({
29        #[cfg(debug_assertions)]
30        {
31            let current_level = unsafe { CURRENT_LEVEL };
32            if $level <= current_level {
33                let indentation = unsafe { "\t".repeat(INDENTATION) };
34                println!("{}{}", indentation, format!($($arg)*));
35            }
36        }
37    });
38}
39
40pub struct Serializer {
41    // This string starts empty and JSON is appended as values are serialized.
42    output: String,
43    indentation: usize,
44    array_key: Option<String>,
45}
46
47// By convention, the public API of a Serde serializer is one or more `to_abc`
48// functions such as `to_string`, `to_bytes`, or `to_writer` depending on what
49// Rust types the serializer is able to produce as output.
50//
51// This basic serializer supports only `to_string`.
52pub fn to_string<T>(value: &T) -> Result<String>
53where
54    T: Serialize,
55{
56    let mut serializer = Serializer {
57        output: String::new(),
58        indentation: 0,
59        array_key: None,
60    };
61    value.serialize(&mut serializer)?;
62
63    log!(
64        LogLevel::Debug,
65        "Serializer Output:\n{:?}",
66        serializer.output
67    );
68
69    {
70        let mut temp_output = serializer.output.clone();
71
72        // Run a preprocessor over the serialized output.
73        if peek_expect_char(&serializer.output, 0, '"').unwrap_or(false) {
74            let header = parse_string(&temp_output)?;
75            temp_output = header.1.to_string();
76
77            if peek_expect_char(&temp_output, 0, '{').unwrap_or(false) {
78                log!(LogLevel::Debug, "Preprocessing serializer...");
79                serializer.output = preprocess(&serializer.output, true, true).unwrap();
80            }
81        }
82    }
83
84    Ok(serializer.output)
85}
86
87impl<'a> ser::Serializer for &'a mut Serializer {
88    // The output type produced by this `Serializer` during successful
89    // serialization. Most serializers that produce text or binary output should
90    // set `Ok = ()` and serialize into an `io::Write` or buffer contained
91    // within the `Serializer` instance, as happens here. Serializers that build
92    // in-memory data structures may be simplified by using `Ok` to propagate
93    // the data structure around.
94    type Ok = ();
95
96    // The error type when some error occurs during serialization.
97    type Error = Error;
98
99    // Associated types for keeping track of additional state while serializing
100    // compound data structures like sequences and maps. In this case no
101    // additional state is required beyond what is already stored in the
102    // Serializer struct.
103    type SerializeSeq = Self;
104    type SerializeTuple = Self;
105    type SerializeTupleStruct = Self;
106    type SerializeTupleVariant = Self;
107    type SerializeMap = Self;
108    type SerializeStruct = Self;
109    type SerializeStructVariant = Self;
110
111    // Here we go with the simple methods. The following 12 methods receive one
112    // of the primitive types of the data model and map it to JSON by appending
113    // into the output string.
114    fn serialize_bool(self, v: bool) -> Result<()> {
115        self.output += if v { "\"1\"" } else { "\"0\"" };
116        Ok(())
117    }
118
119    // JSON does not distinguish between different sizes of integers, so all
120    // signed integers will be serialized the same and all unsigned integers
121    // will be serialized the same. Other formats, especially compact binary
122    // formats, may need independent logic for the different sizes.
123    fn serialize_i8(self, v: i8) -> Result<()> {
124        self.serialize_i64(i64::from(v))
125    }
126
127    fn serialize_i16(self, v: i16) -> Result<()> {
128        self.serialize_i64(i64::from(v))
129    }
130
131    fn serialize_i32(self, v: i32) -> Result<()> {
132        self.serialize_i64(i64::from(v))
133    }
134
135    // Not particularly efficient but this is example code anyway. A more
136    // performant approach would be to use the `itoa` crate.
137    fn serialize_i64(self, v: i64) -> Result<()> {
138        self.output += &format!("\"{}\"", v).to_string();
139        Ok(())
140    }
141
142    fn serialize_u8(self, v: u8) -> Result<()> {
143        self.serialize_u64(u64::from(v))
144    }
145
146    fn serialize_u16(self, v: u16) -> Result<()> {
147        self.serialize_u64(u64::from(v))
148    }
149
150    fn serialize_u32(self, v: u32) -> Result<()> {
151        self.serialize_u64(u64::from(v))
152    }
153
154    fn serialize_u64(self, v: u64) -> Result<()> {
155        self.output += &format!("\"{}\"", v).to_string();
156        Ok(())
157    }
158
159    fn serialize_f32(self, v: f32) -> Result<()> {
160        self.serialize_f64(f64::from(v))
161    }
162
163    fn serialize_f64(self, v: f64) -> Result<()> {
164        self.output += &format!("\"{}\"", v).to_string();
165        Ok(())
166    }
167
168    // Serialize a char as a single-character string. Other formats may
169    // represent this differently.
170    fn serialize_char(self, v: char) -> Result<()> {
171        self.serialize_str(&v.to_string())
172    }
173
174    // This only works for strings that don't require escape sequences but you
175    // get the idea. For example it would emit invalid JSON if the input string
176    // contains a '"' character.
177    fn serialize_str(self, v: &str) -> Result<()> {
178        self.output += &format!("\"{}\"", v).to_string();
179        self.array_key = Some(v.to_string());
180        Ok(())
181    }
182
183    // Serialize a byte array as an array of bytes. Could also use a base64
184    // string here. Binary formats will typically represent byte arrays more
185    // compactly.
186    fn serialize_bytes(self, v: &[u8]) -> Result<()> {
187        use serde::ser::SerializeSeq;
188        let mut seq = self.serialize_seq(Some(v.len()))?;
189        for byte in v {
190            seq.serialize_element(byte)?;
191        }
192        seq.end()
193    }
194
195    // An absent optional is represented as the JSON `null`.
196    fn serialize_none(self) -> Result<()> {
197        self.serialize_unit()
198    }
199
200    // A present optional is represented as just the contained value. Note that
201    // this is a lossy representation. For example the values `Some(())` and
202    // `None` both serialize as just `null`. Unfortunately this is typically
203    // what people expect when working with JSON. Other formats are encouraged
204    // to behave more intelligently if possible.
205    fn serialize_some<T>(self, value: &T) -> Result<()>
206    where
207        T: ?Sized + Serialize,
208    {
209        value.serialize(self)
210    }
211
212    // In Serde, unit means an anonymous value containing no data. Map this to
213    // JSON as `null`.
214    fn serialize_unit(self) -> Result<()> {
215        self.output += "null";
216        Ok(())
217    }
218
219    // Unit struct means a named value containing no data. Again, since there is
220    // no data, map this to JSON as `null`. There is no need to serialize the
221    // name in most formats.
222    fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
223        self.serialize_unit()
224    }
225
226    // When serializing a unit variant (or any other kind of variant), formats
227    // can choose whether to keep track of it by index or by name. Binary
228    // formats typically use the index of the variant and human-readable formats
229    // typically use the name.
230    fn serialize_unit_variant(
231        self,
232        _name: &'static str,
233        _variant_index: u32,
234        variant: &'static str,
235    ) -> Result<()> {
236        self.serialize_str(variant)
237    }
238
239    // As is done here, serializers are encouraged to treat newtype structs as
240    // insignificant wrappers around the data they contain.
241    fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
242    where
243        T: ?Sized + Serialize,
244    {
245        value.serialize(self)
246    }
247
248    // Note that newtype variant (and all of the other variant serialization
249    // methods) refer exclusively to the "externally tagged" enum
250    // representation.
251    //
252    // Serialize this to JSON in externally tagged form as `{ NAME: VALUE }`.
253    fn serialize_newtype_variant<T>(
254        self,
255        _name: &'static str,
256        _variant_index: u32,
257        _variant: &'static str,
258        value: &T,
259    ) -> Result<()>
260    where
261        T: ?Sized + Serialize,
262    {
263        value.serialize(&mut *self)?;
264        Ok(())
265    }
266
267    // Now we get to the serialization of compound types.
268    //
269    // The start of the sequence, each value, and the end are three separate
270    // method calls. This one is responsible only for serializing the start,
271    // which in JSON is `[`.
272    //
273    // The length of the sequence may or may not be known ahead of time. This
274    // doesn't make a difference in JSON because the length is not represented
275    // explicitly in the serialized form. Some serializers may only be able to
276    // support sequences for which the length is known up front.
277    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
278        // Delete the last key, since we are about to serialize a sequence.
279        // let key = self.array_key.clone().unwrap();
280        // let loc = self.output.rfind(format!("\"{}\"", key).as_str()).unwrap();
281        // self.output = self.output[..loc].to_string();
282        Ok(self)
283    }
284
285    fn collect_seq<I>(self, iter: I) -> std::result::Result<Self::Ok, Self::Error>
286    where
287        I: IntoIterator,
288        <I as IntoIterator>::Item: Serialize,
289    {
290        if self.array_key.is_none() {
291            panic!("Expected a key before a sequence.");
292        }
293
294        let key = self.array_key.clone().unwrap();
295
296        // Delete the last key, since we are about to serialize a sequence.
297        let loc = self
298            .output
299            .rfind(format!("\n{}\"{}\"\t\t", "\t".repeat(self.indentation), key).as_str())
300            .unwrap();
301        self.output = self.output[..loc].to_string();
302
303        let seq = self.serialize_seq(None)?;
304        for value in iter {
305            // Skip the first element, since it is the key.
306            let ends_with_key = seq.output.ends_with(key.as_str());
307            if !ends_with_key {
308                seq.output += "\n";
309                seq.output += "\t".repeat(seq.indentation).as_str();
310                // seq.output += "sek";
311                key.serialize(&mut *seq)?;
312            }
313            seq.output += "\t\t";
314            // seq.output += "sev";
315            value.serialize(&mut *seq)?;
316        }
317        seq.end()?;
318        self.array_key = None;
319        Ok(())
320    }
321
322    // Tuples look just like sequences in JSON. Some formats may be able to
323    // represent tuples more efficiently by omitting the length, since tuple
324    // means that the corresponding `Deserialize implementation will know the
325    // length without needing to look at the serialized data.
326    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
327        Ok(self)
328    }
329
330    // Tuple structs look just like sequences in JSON.
331    fn serialize_tuple_struct(
332        self,
333        _name: &'static str,
334        _len: usize,
335    ) -> Result<Self::SerializeTupleStruct> {
336        Ok(self)
337    }
338
339    // Tuple variants are represented in JSON as `{ NAME: [DATA...] }`. Again
340    // this method is only responsible for the externally tagged representation.
341    fn serialize_tuple_variant(
342        self,
343        _name: &'static str,
344        _variant_index: u32,
345        _variant: &'static str,
346        _len: usize,
347    ) -> Result<Self::SerializeTupleVariant> {
348        Ok(self)
349    }
350
351    // Maps are represented in JSON as `{ K: V, K: V, ... }`.
352    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
353        if self.output.len() > 0 {
354            self.output += "\n";
355            self.output += "\t".repeat(self.indentation).as_str();
356            self.output += "{\n";
357            self.indentation += 1;
358        }
359        Ok(self)
360    }
361
362    // Structs look just like maps in JSON. In particular, JSON requires that we
363    // serialize the field names of the struct. Other formats may be able to
364    // omit the field names when serializing structs because the corresponding
365    // Deserialize implementation is required to know what the keys are without
366    // looking at the serialized data.
367    fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
368        // if self.output.len() == 0 {
369        //     self.output += " ";
370        // }
371
372        self.serialize_map(Some(len))
373    }
374
375    // Struct variants are represented in JSON as `{ NAME: { K: V, ... } }`.
376    // This is the externally tagged representation.
377    fn serialize_struct_variant(
378        self,
379        _name: &'static str,
380        _variant_index: u32,
381        _variant: &'static str,
382        _len: usize,
383    ) -> Result<Self::SerializeStructVariant> {
384        self.output += "\n";
385        self.output += "\t".repeat(self.indentation).as_str();
386        self.output += "{\n";
387        self.indentation += 1;
388        Ok(self)
389    }
390}
391
392// The following 7 impls deal with the serialization of compound types like
393// sequences and maps. Serialization of such types is begun by a Serializer
394// method and followed by zero or more calls to serialize individual elements of
395// the compound type and one call to end the compound type.
396//
397// This impl is SerializeSeq so these methods are called after `serialize_seq`
398// is called on the Serializer.
399impl<'a> ser::SerializeSeq for &'a mut Serializer {
400    // Must match the `Ok` type of the serializer.
401    type Ok = ();
402    // Must match the `Error` type of the serializer.
403    type Error = Error;
404
405    // Serialize a single element of the sequence.
406    fn serialize_element<T>(&mut self, _value: &T) -> Result<()>
407    where
408        T: ?Sized + Serialize,
409    {
410        Ok(())
411    }
412
413    // Close the sequence.
414    fn end(self) -> Result<()> {
415        self.output = self.output.trim().to_string();
416        Ok(())
417    }
418}
419
420// Some `Serialize` types are not able to hold a key and value in memory at the
421// same time so `SerializeMap` implementations are required to support
422// `serialize_key` and `serialize_value` individually.
423//
424// There is a third optional method on the `SerializeMap` trait. The
425// `serialize_entry` method allows serializers to optimize for the case where
426// key and value are both available simultaneously.
427impl<'a> ser::SerializeMap for &'a mut Serializer {
428    type Ok = ();
429    type Error = Error;
430
431    fn serialize_key<T>(&mut self, key: &T) -> Result<()>
432    where
433        T: ?Sized + Serialize,
434    {
435        self.output += "\n";
436        self.output += "\t".repeat(self.indentation).as_str();
437        key.serialize(&mut **self)
438    }
439
440    // It doesn't make a difference whether the colon is printed at the end of
441    // `serialize_key` or at the beginning of `serialize_value`. In this case
442    // the code is a bit simpler having it here.
443    fn serialize_value<T>(&mut self, value: &T) -> Result<()>
444    where
445        T: ?Sized + Serialize,
446    {
447        self.output += "\t\t";
448        value.serialize(&mut **self)
449    }
450
451    fn end(self) -> Result<()> {
452        if self.indentation > 0 {
453            self.indentation -= 1;
454            self.output += "\n";
455            self.output += "\t".repeat(self.indentation).as_str();
456            self.output += "}";
457        }
458        Ok(())
459    }
460}
461
462// Structs are like maps in which the keys are constrained to be compile-time
463// constant strings.
464impl<'a> ser::SerializeStruct for &'a mut Serializer {
465    type Ok = ();
466    type Error = Error;
467
468    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
469    where
470        T: ?Sized + Serialize,
471    {
472        self.output += "\t".repeat(self.indentation).as_str();
473        key.serialize(&mut **self)?;
474        self.output += "\t\t";
475        let result = value.serialize(&mut **self);
476        self.output += "\n";
477        result
478    }
479
480    fn end(self) -> Result<()> {
481        if self.indentation > 0 {
482            self.indentation -= 1;
483            self.output += "\n";
484            self.output += "\t".repeat(self.indentation).as_str();
485            self.output += "}";
486        }
487        Ok(())
488    }
489}
490
491// Similar to `SerializeTupleVariant`, here the `end` method is responsible for
492// closing both of the curly braces opened by `serialize_struct_variant`.
493impl<'a> ser::SerializeStructVariant for &'a mut Serializer {
494    type Ok = ();
495    type Error = Error;
496
497    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
498    where
499        T: ?Sized + Serialize,
500    {
501        self.output += "\t".repeat(self.indentation).as_str();
502        key.serialize(&mut **self)?;
503        self.output += "\t\t";
504        let result = value.serialize(&mut **self);
505        self.output += "\n";
506        result
507    }
508
509    fn end(self) -> Result<()> {
510        self.indentation -= 1;
511        self.output += "\t".repeat(self.indentation).as_str();
512        self.output += "}";
513        Ok(())
514    }
515}
516
517// Tuple Structs aren't supported, because they don't have keys of the fields.
518// So we cannot map them, as in VDF format is built on mappable sequences.
519impl<'a> ser::SerializeTupleStruct for &'a mut Serializer {
520    type Ok = ();
521    type Error = Error;
522
523    fn serialize_field<T>(&mut self, _value: &T) -> Result<()>
524    where
525        T: ?Sized + Serialize,
526    {
527        Err(Error::CannotSupportedTupleType)
528    }
529
530    fn end(self) -> Result<()> {
531        Ok(())
532    }
533}
534
535// Tuple Variants aren't supported, because they don't have keys of the fields.
536// So we cannot map them, as in VDF format is built on mappable sequences.
537impl<'a> ser::SerializeTupleVariant for &'a mut Serializer {
538    type Ok = ();
539    type Error = Error;
540
541    fn serialize_field<T>(&mut self, _value: &T) -> Result<()>
542    where
543        T: ?Sized + Serialize,
544    {
545        Err(Error::CannotSupportedTupleType)
546    }
547
548    fn end(self) -> Result<()> {
549        Ok(())
550    }
551}
552// Plain Tuple aren't supported, because they don't have keys of the fields.
553// So we cannot map them, as in VDF format is built on mappable sequences.
554impl<'a> ser::SerializeTuple for &'a mut Serializer {
555    type Ok = ();
556    type Error = Error;
557
558    fn serialize_element<T>(&mut self, _value: &T) -> Result<()>
559    where
560        T: ?Sized + Serialize,
561    {
562        Err(Error::CannotSupportedTupleType)
563    }
564
565    fn end(self) -> Result<()> {
566        Ok(())
567    }
568}
569
570////////////////////////////////////////////////////////////////////////////////
571#[cfg(test)]
572mod tests {
573    use super::*;
574
575    mod enums {
576        use super::*;
577
578        #[derive(Serialize)]
579        struct TestTupleStruct(u32, u32);
580
581        #[derive(Serialize)]
582        enum Test {
583            A(String),            // This will succeed. Enum Variant Primitives are supported.
584            B(bool),              // This will succeed. Enum Variant Primitives are supported.
585            C { x: i32, y: i32 }, // This will succeed. Enum Variant Struct are supported.
586            D((i32, i32)),        // This will fail.  Enum Tuple are not supported.
587            E(String, i32),       // This will fail.  Enum Tuple Variant are not supported.
588            F(TestTupleStruct),   // This will fail.  Enum Struct Tuple structs are not supported.
589        }
590        #[derive(Serialize)]
591        struct TestContainer {
592            test: Test,
593        }
594
595        #[test]
596        fn supported_enum_variant_string() {
597            log!(LogLevel::Debug, "Test A(String) - Enum Variant / Primitive");
598            let result = TestContainer {
599                test: Test::A("Hello World!".to_string()),
600            };
601
602            let expected = r#"
603                "test"        "Hello World!"
604            "#;
605            let result_str = to_string(&result).unwrap();
606            log!(LogLevel::Debug, "Result:\n{}", result_str);
607
608            // Remove all whitespace for assertion test.
609            let result_str = result_str.replace(|c: char| c.is_whitespace(), "");
610            let expected_str = expected.replace(|c: char| c.is_whitespace(), "");
611            assert_eq!(result_str, expected_str);
612        }
613
614        #[test]
615        fn supported_enum_variant_bool() {
616            log!(LogLevel::Debug, "Test B(bool) - Enum Variant / Primitive");
617            let result = TestContainer {
618                test: Test::B(true),
619            };
620
621            let expected = r#"
622                "test"        "1"
623            "#;
624            let result_str = to_string(&result).unwrap();
625            log!(LogLevel::Debug, "Result:\n{}", result_str);
626
627            // Remove all whitespace for assertion test.
628            let result_str = result_str.replace(|c: char| c.is_whitespace(), "");
629            let expected_str = expected.replace(|c: char| c.is_whitespace(), "");
630            assert_eq!(result_str, expected_str);
631        }
632
633        #[test]
634        fn supported_enum_variant_struct() {
635            log!(
636                LogLevel::Debug,
637                "Test C {{ x: i32, y: i32 }} - Enum Variant / Struct"
638            );
639            let result = TestContainer {
640                test: Test::C { x: 1, y: 2 },
641            };
642
643            let expected = r#"
644                "test"        
645                {
646                    "x"      "1"
647                    "y"      "2"
648                }
649            "#;
650            let result_str = to_string(&result).unwrap();
651            log!(LogLevel::Debug, "Result:\n{}", result_str);
652
653            // Remove all whitespace for assertion test.
654            let result_str = result_str.replace(|c: char| c.is_whitespace(), "");
655            let expected_str = expected.replace(|c: char| c.is_whitespace(), "");
656            assert_eq!(result_str, expected_str);
657        }
658
659        #[test]
660        fn unsupported_tuple_variant_enum() {
661            log!(
662                LogLevel::Debug,
663                "Test D((i32, i32)) - Tuple Variant Enum - Expected to Fail, unsupported tuple type"
664            );
665            let result = TestContainer {
666                test: Test::D((1, 2)),
667            };
668            let result = to_string(&result).is_err();
669            assert!(result);
670        }
671
672        #[test]
673        fn unsupported_enum_tuple_variant() {
674            log!(
675                LogLevel::Debug,
676                "Test E(String, i32) - Enum Tuple Variant - Expected to Fail, unsupported tuple type"
677            );
678            let result = TestContainer {
679                test: Test::E("Hello World!".to_string(), 1),
680            };
681
682            let result = to_string(&result).is_err();
683            assert!(result);
684        }
685
686        #[test]
687        fn unsupported_enum_tuple_struct() {
688            log!(
689                LogLevel::Debug,
690                "Test F(TestTupleStruct) - Tuple Struct - Expected to Fail, unsupported tuple type"
691            );
692            let result = TestContainer {
693                test: Test::F(TestTupleStruct(1, 2)),
694            };
695
696            let result = to_string(&result).is_err();
697            assert!(result);
698        }
699    }
700
701    mod primitives {
702        use super::*;
703
704        #[test]
705        fn supported_strs() {
706            let result = "Hello World!";
707            let expected = r#""Hello World!""#;
708            let result_str = to_string(&result).unwrap();
709            assert_eq!(result_str, expected);
710        }
711
712        #[test]
713        fn supported_bool_true() {
714            let result = true;
715            let expected = r#""1""#;
716            let result_str = to_string(&result).unwrap();
717            assert_eq!(result_str, expected);
718        }
719
720        #[test]
721        fn supported_bool_false() {
722            let result = false;
723            let expected = r#""0""#;
724            let result_str = to_string(&result).unwrap();
725            assert_eq!(result_str, expected);
726        }
727
728        #[test]
729        fn supported_i8() {
730            let result = 1i8;
731            let expected = r#""1""#;
732            let result_str = to_string(&result).unwrap();
733            assert_eq!(result_str, expected);
734        }
735
736        #[test]
737        fn supported_i16() {
738            let result = 1i16;
739            let expected = r#""1""#;
740            let result_str = to_string(&result).unwrap();
741            assert_eq!(result_str, expected);
742        }
743
744        #[test]
745        fn supported_i32() {
746            let result = 1i32;
747            let expected = r#""1""#;
748            let result_str = to_string(&result).unwrap();
749            assert_eq!(result_str, expected);
750        }
751
752        #[test]
753        fn supported_i64() {
754            let result = 1i64;
755            let expected = r#""1""#;
756            let result_str = to_string(&result).unwrap();
757            assert_eq!(result_str, expected);
758        }
759
760        #[test]
761        fn supported_u8() {
762            let result = 1u8;
763            let expected = r#""1""#;
764            let result_str = to_string(&result).unwrap();
765            assert_eq!(result_str, expected);
766        }
767
768        #[test]
769        fn supported_u16() {
770            let result = 1u16;
771            let expected = r#""1""#;
772            let result_str = to_string(&result).unwrap();
773            assert_eq!(result_str, expected);
774        }
775
776        #[test]
777        fn supported_u32() {
778            let result = 1u32;
779            let expected = r#""1""#;
780            let result_str = to_string(&result).unwrap();
781            assert_eq!(result_str, expected);
782        }
783
784        #[test]
785        fn supported_u64() {
786            let result = 1u64;
787            let expected = r#""1""#;
788            let result_str = to_string(&result).unwrap();
789            assert_eq!(result_str, expected);
790        }
791
792        #[test]
793        fn supported_f32() {
794            let result = 0.25f32;
795            let expected = r#""0.25""#;
796            let result_str = to_string(&result).unwrap();
797            assert_eq!(result_str, expected);
798        }
799
800        #[test]
801        fn supported_f64() {
802            let result = 0.45f64;
803            let expected = r#""0.45""#;
804            let result_str = to_string(&result).unwrap();
805            assert_eq!(result_str, expected);
806        }
807    }
808
809    mod structs {
810        use super::*;
811
812        #[derive(Serialize)]
813        struct Test {
814            int: u32,
815            seq: Vec<&'static str>,
816        }
817
818        #[derive(Serialize)]
819        struct TestContainer {
820            test: Test,
821        }
822
823        #[test]
824        fn supported_struct() {
825            let test = Test {
826                int: 1,
827                seq: vec!["a", "b"],
828            };
829
830            let expected = r#"
831                "int"       "1"
832                "seq"       "a"
833                "seq"       "b"
834            "#;
835            let result_str = to_string(&test).unwrap();
836            log!(LogLevel::Debug, "Result:\n{}", result_str);
837
838            // Remove all whitespace for assertion test.
839            let result_str = result_str.replace(|c: char| c.is_whitespace(), "");
840            let expected_str = expected.replace(|c: char| c.is_whitespace(), "");
841            assert_eq!(result_str, expected_str);
842        }
843
844        #[test]
845        fn supported_mapped_struct() {
846            let test = Test {
847                int: 1,
848                seq: vec!["a", "b"],
849            };
850            let result = TestContainer { test };
851
852            let expected = r#"
853                "test"        
854                {
855                    "int"      "1"
856                    "seq"       "a"
857                    "seq"       "b"
858                }
859            "#;
860            let result_str = format!("\n{}\n", to_string(&result).unwrap());
861            log!(LogLevel::Debug, "Result:\n{}", result_str);
862
863            // Remove all whitespace for assertion test.
864            let result_str = result_str.replace(|c: char| c.is_whitespace(), "");
865            let expected_str = expected.replace(|c: char| c.is_whitespace(), "");
866            assert_eq!(result_str, expected_str);
867        }
868    }
869
870    mod advanced {
871        use super::*;
872
873        #[test]
874        fn test_struct_nested_list() {
875            #[derive(Serialize)]
876            struct Data {
877                name: String,
878                list_str: Vec<String>,
879                map: std::collections::HashMap<String, i64>,
880            }
881
882            #[derive(Serialize)]
883            struct Test {
884                int: u32,
885                seq: Vec<Data>,
886            }
887            #[derive(Serialize)]
888            struct TestContainer {
889                test: Test,
890            }
891
892            let test = Test {
893                int: 1,
894                seq: vec![
895                    Data {
896                        name: "Better VDF".to_string(),
897                        list_str: vec![
898                            "value1".to_string(),
899                            "value2".to_string(),
900                            "value3".to_string(),
901                        ],
902                        map: [
903                            ("zbx".to_string(), 12318293),
904                            ("thc".to_string(), -12393180),
905                        ]
906                        .iter()
907                        .cloned()
908                        .collect(),
909                    },
910                    Data {
911                        name: "rrrrr".to_string(),
912                        list_str: vec![
913                            "1243".to_string(),
914                            "sadferw".to_string(),
915                            "batebt".to_string(),
916                        ],
917                        map: vec![("abc".to_string(), 444444), ("key".to_string(), -555555)]
918                            .iter()
919                            .cloned()
920                            .collect(),
921                    },
922                ],
923            };
924            let result = TestContainer { test };
925
926            let expected = r#"
927            "test"
928            {
929                "seq"       
930                {
931                    "list_str" "value1"
932                    "name"     "Better VDF"
933                    "list_str" "value2"
934                    "list_str" "value3"
935                    "map"      
936                    {
937                        "thc"  "-12393180"
938                        "zbx"  "12318293"
939                    }
940                }
941                "int"      "1"
942                "seq"       
943                {
944                    "name"     "rrrrr"
945                    "list_str" "1243"
946                    "list_str" "sadferw"
947                    "list_str" "batebt"
948                    "map"      
949                    {
950                        "key"  "-555555"
951                        "abc"  "444444"
952                    }
953                }
954            }
955            "#;
956            let result_str = to_string(&result).unwrap();
957            log!(LogLevel::Debug, "Result:\n{}", result_str);
958
959            // Remove all whitespace for assertion test.
960            let result_str = result_str.replace(|c: char| c.is_whitespace(), "");
961            let expected_str = preprocess(&expected, true, true).unwrap();
962            log!(LogLevel::Debug, "Expected:\n{}", expected_str);
963            let expected_str = expected_str.replace(|c: char| c.is_whitespace(), "");
964            assert_eq!(result_str, expected_str);
965        }
966    }
967}