1// Copyright (c) 2023 Huawei Device Co., Ltd.
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6//     http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14use crate::encoder::encode_string_inner;
15use crate::{Error, Error::*};
16use serde::{ser, ser::SerializeSeq, Serialize};
17
18/// A data format that can serialize any data structure supported by Serde.
19struct Serializer<W>
20where
21    W: std::io::Write,
22{
23    writer: W,
24    element_num: Vec<usize>, // Used to record the number of traveled elements in the sequence.
25}
26
27/// An auxiliary struct which implements Write trait used in 'to_string' function.
28struct AuxiliaryWriter {
29    output: Vec<u8>,
30}
31
32impl std::io::Write for AuxiliaryWriter {
33    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
34        self.output.extend_from_slice(buf);
35        Ok(buf.len())
36    }
37
38    fn flush(&mut self) -> std::io::Result<()> {
39        Ok(())
40    }
41}
42
43/// ylong_json::serializer_compact supports two functions to produce as output: 'to_string' and 'to_writer'.
44///
45/// The to_string function serialize an instance which implements the Serialize Trait to a string and return.
46pub fn to_string<T>(value: &T) -> Result<String, Error>
47where
48    T: Serialize,
49{
50    let mut writer = AuxiliaryWriter { output: Vec::new() };
51    to_writer(value, &mut writer)?;
52    Ok(unsafe { String::from_utf8_unchecked(writer.output) })
53}
54
55/// The to_writer function serialize an instance which implements the Serialize Trait and
56/// writes result into the writer passed in by the user, which needs to implement the std::io::Write.
57pub fn to_writer<T, W>(value: &T, writer: &mut W) -> Result<(), Error>
58where
59    T: Serialize,
60    W: std::io::Write,
61{
62    let mut serializer = Serializer {
63        writer,
64        element_num: Vec::new(),
65    };
66    value.serialize(&mut serializer)?;
67    Ok(())
68}
69
70impl<'a, W: std::io::Write> ser::Serializer for &'a mut Serializer<W> {
71    // Using `Ok` to propagate the data structure around simplifies Serializers
72    // which build in-memory data structures. Set 'ok=()' and write the serialization
73    // result to the buffer contained by the instance.
74    type Ok = ();
75
76    // The error type when serializing an instance may occur.
77    type Error = Error;
78
79    // Associative type composite data structures, such as sequences and maps,
80    // used to track other states at serialization time. In this case, no state
81    // is required other than what is already stored in the Serializer struct.
82    type SerializeSeq = Self;
83    type SerializeMap = Self;
84    type SerializeStruct = Self;
85    type SerializeStructVariant = Self;
86    type SerializeTuple = Self;
87    type SerializeTupleStruct = Self;
88    type SerializeTupleVariant = Self;
89
90    // The following 12 methods take one of the base types of the data model
91    // and map it to JSON by appending it to the output string.
92    fn serialize_bool(self, v: bool) -> Result<(), Error> {
93        self.writer.write_fmt(format_args!("{v}"))?;
94        Ok(())
95    }
96
97    // JSON does not distinguish between integers of different sizes,
98    // so all signed integers and all unsigned integers will be serialized in the same way.
99    // Therefore, all integers are converted to 64-bit integers and serialized here.
100    fn serialize_i8(self, v: i8) -> Result<(), Error> {
101        self.serialize_i64(i64::from(v))
102    }
103
104    fn serialize_i16(self, v: i16) -> Result<(), Error> {
105        self.serialize_i64(i64::from(v))
106    }
107
108    fn serialize_i32(self, v: i32) -> Result<(), Error> {
109        self.serialize_i64(i64::from(v))
110    }
111
112    fn serialize_i64(self, v: i64) -> Result<(), Error> {
113        self.writer.write_fmt(format_args!("{v}"))?;
114        Ok(())
115    }
116
117    fn serialize_u8(self, v: u8) -> Result<(), Error> {
118        self.serialize_u64(u64::from(v))
119    }
120
121    fn serialize_u16(self, v: u16) -> Result<(), Error> {
122        self.serialize_u64(u64::from(v))
123    }
124
125    fn serialize_u32(self, v: u32) -> Result<(), Error> {
126        self.serialize_u64(u64::from(v))
127    }
128
129    fn serialize_u64(self, v: u64) -> Result<(), Error> {
130        self.writer.write_fmt(format_args!("{v}"))?;
131        Ok(())
132    }
133
134    // Same way for floating-point types.
135    fn serialize_f32(self, v: f32) -> Result<(), Error> {
136        self.serialize_f64(f64::from(v))
137    }
138
139    fn serialize_f64(self, v: f64) -> Result<(), Error> {
140        self.writer.write_fmt(format_args!("{v:?}"))?;
141        Ok(())
142    }
143
144    fn serialize_char(self, v: char) -> Result<(), Error> {
145        self.serialize_str(v.encode_utf8(&mut [0; 4]))
146    }
147
148    fn serialize_str(self, v: &str) -> Result<(), Error> {
149        self.writer.write_all(b"\"")?;
150        encode_string_inner(&mut self.writer, v)?;
151        self.writer.write_all(b"\"")?;
152        Ok(())
153    }
154
155    // Serialize a byte array into an array of bytes.
156    // Binary formats will typically represent byte arrays more compactly.
157    fn serialize_bytes(self, v: &[u8]) -> Result<(), Error> {
158        let mut seq = self.serialize_seq(Some(v.len()))?;
159        for byte in v {
160            seq.serialize_element(byte)?;
161        }
162        seq.end()
163    }
164
165    // JSON `null` represent an absent optional.
166    fn serialize_none(self) -> Result<(), Error> {
167        self.serialize_unit()
168    }
169
170    // Represent an optional instance as the contained value.
171    fn serialize_some<T>(self, value: &T) -> Result<(), Error>
172    where
173        T: ?Sized + Serialize,
174    {
175        value.serialize(self)
176    }
177
178    // In Serde, unit represents an anonymous value that does not contain any data.
179    // Map this to JSON as "null".
180    fn serialize_unit(self) -> Result<(), Error> {
181        self.writer.write_all(b"null")?;
182        Ok(())
183    }
184
185    // Unit struct represents a named value that does not contain any data. Map it to JSON as "null".
186    fn serialize_unit_struct(self, _name: &'static str) -> Result<(), Error> {
187        self.serialize_unit()
188    }
189
190    // When serializing a unit variant (or any other kind of variant), formats
191    // can choose whether to track it by index or by name. Binary formats
192    // usually use index while human-readable formats usually use name.
193    fn serialize_unit_variant(
194        self,
195        _name: &'static str,
196        _variant_index: u32,
197        variant: &'static str, // The name of the variant.
198    ) -> Result<(), Error> {
199        self.serialize_str(variant)
200    }
201
202    // Treat newtype structs as insignificant wrappers for the data they contain.
203    fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<(), Error>
204    where
205        T: ?Sized + Serialize,
206    {
207        value.serialize(self)
208    }
209
210    // The newtype variant (and all other variant serialization methods)
211    // specifically refers to the enumerated representation of the "externally tagged".
212    //
213    // Serialize it to JSON with an outer tag of the form '{NAME: VALUE}'.
214    fn serialize_newtype_variant<T>(
215        self,
216        _name: &'static str,
217        _variant_index: u32,
218        variant: &'static str, // The name of the variant.
219        value: &T,
220    ) -> Result<(), Error>
221    where
222        T: ?Sized + Serialize,
223    {
224        self.writer.write_all(b"{")?;
225        variant.serialize(&mut *self)?;
226        self.writer.write_all(b":")?;
227        value.serialize(&mut *self)?;
228        self.writer.write_all(b"}")?;
229        Ok(())
230    }
231
232    // The following is the serialization of compound types.
233    // The start of the sequence, each value, and the end use three separate method calls.
234    // The serializer can be able to support sequences for which the length is unknown up front.
235    //
236    // This one used to serialize the start of the sequence, which in JSON is `[`.
237    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Error> {
238        self.element_num.push(0); // Now there is no element in this sequence.
239        self.writer.write_all(b"[")?;
240        Ok(self)
241    }
242
243    // Tuples and sequences are represented similarly in JSON.
244    // Some formats can represent tuples more efficiently by omitting the length.
245    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Error> {
246        self.serialize_seq(Some(len))
247    }
248
249    // Tuple and sequences are represented similarly in JSON.
250    fn serialize_tuple_struct(
251        self,
252        _name: &'static str,
253        len: usize, // The number of data fields that will be serialized.
254    ) -> Result<Self::SerializeTupleStruct, Error> {
255        self.serialize_seq(Some(len))
256    }
257
258    // Tuple variants are represented in JSON as `{ NAME: [DATA...] }`.
259    // This method used only for the externally tagged representation.
260    fn serialize_tuple_variant(
261        self,
262        _name: &'static str,
263        _variant_index: u32,
264        variant: &'static str, // The name of the variant.
265        _len: usize,
266    ) -> Result<Self::SerializeTupleVariant, Error> {
267        self.element_num.push(0);
268        self.writer.write_all(b"{")?;
269        variant.serialize(&mut *self)?;
270        self.writer.write_all(b":[")?;
271        Ok(self)
272    }
273
274    // Maps are represented in JSON as `{ K: V, K: V, ... }`.
275    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Error> {
276        self.element_num.push(0);
277        self.writer.write_all(b"{")?;
278        Ok(self)
279    }
280
281    // Structs and maps are represented similarly in JSON.
282    fn serialize_struct(
283        self,
284        _name: &'static str,
285        len: usize, // The number of data fields that will be serialized.
286    ) -> Result<Self::SerializeStruct, Error> {
287        self.serialize_map(Some(len))
288    }
289
290    // Struct variants are represented in JSON as `{ NAME: { K: V, ... } }`.
291    // This used for the externally tagged representation.
292    fn serialize_struct_variant(
293        self,
294        _name: &'static str,
295        _variant_index: u32,
296        variant: &'static str, // The name of the variant.
297        _len: usize,
298    ) -> Result<Self::SerializeStructVariant, Error> {
299        self.element_num.push(0);
300        self.writer.write_all(b"{")?;
301        variant.serialize(&mut *self)?;
302        self.writer.write_all(b":{")?;
303        Ok(self)
304    }
305}
306
307impl<W> Serializer<W>
308where
309    W: std::io::Write,
310{
311    // Serialize a single member of sequence or map.
312    fn whether_to_add_comma(&mut self) -> Result<(), Error> {
313        match self.element_num.last_mut() {
314            None => return Err(IncorrectSerdeUsage),
315            Some(x) => {
316                // This is not the first element, add a comma before the element.
317                if *x > 0 {
318                    self.writer.write_all(b",")?
319                };
320                *x += 1;
321            }
322        }
323        Ok(())
324    }
325
326    // Add another half of the parentheses at the end.
327    fn add_another_half(&mut self, buf: &[u8]) -> Result<(), Error> {
328        self.writer.write_all(buf)?;
329        Ok(())
330    }
331}
332
333// The following 7 impls used to serialize compound types like sequences and maps.
334// At the beginning of serializing such types, one call of Serializer method.
335// Next, zero or more calls which serializes a single element of the compound type.
336// Finally, one call to end the serializing of the compound type.
337//
338// This impl is SerializeSeq so these methods are called after calling 'serialize_seq' on Serializer.
339impl<'a, W: std::io::Write> ser::SerializeSeq for &'a mut Serializer<W> {
340    // Must match the `Ok` type of the serializer.
341    type Ok = ();
342    // Must match the `Error` type of the serializer.
343    type Error = Error;
344
345    // Serialize a single element in the sequence.
346    fn serialize_element<T>(&mut self, value: &T) -> Result<(), Error>
347    where
348        T: ?Sized + Serialize,
349    {
350        self.whether_to_add_comma()?;
351        value.serialize(&mut **self)
352    }
353
354    // Close the sequence.
355    fn end(self) -> Result<(), Error> {
356        self.element_num.pop();
357        self.add_another_half(b"]")
358    }
359}
360
361// Same thing but for tuples.
362impl<'a, W: std::io::Write> ser::SerializeTuple for &'a mut Serializer<W> {
363    type Ok = ();
364    type Error = Error;
365
366    fn serialize_element<T>(&mut self, value: &T) -> Result<(), Error>
367    where
368        T: ?Sized + Serialize,
369    {
370        self.whether_to_add_comma()?;
371        value.serialize(&mut **self)
372    }
373
374    fn end(self) -> Result<(), Error> {
375        self.element_num.pop();
376        self.add_another_half(b"]")
377    }
378}
379
380// Same thing but for tuple structs.
381impl<'a, W: std::io::Write> ser::SerializeTupleStruct for &'a mut Serializer<W> {
382    type Ok = ();
383    type Error = Error;
384
385    fn serialize_field<T>(&mut self, value: &T) -> Result<(), Error>
386    where
387        T: ?Sized + Serialize,
388    {
389        self.whether_to_add_comma()?;
390        value.serialize(&mut **self)
391    }
392
393    fn end(self) -> Result<(), Error> {
394        self.element_num.pop();
395        self.add_another_half(b"]")
396    }
397}
398
399// The tuple variants are slightly different. Refer back to the
400// `serialize_tuple_variant` method above:
401//
402//    self.writer.write_all(b"{");
403//    variant.serialize(&mut *self)?;
404//    self.writer.write_all(b":[");
405//
406// So the `end` method in this impl is responsible for closing
407// both the `]` and the `}`.
408impl<'a, W: std::io::Write> ser::SerializeTupleVariant for &'a mut Serializer<W> {
409    type Ok = ();
410    type Error = Error;
411
412    fn serialize_field<T>(&mut self, value: &T) -> Result<(), Error>
413    where
414        T: ?Sized + Serialize,
415    {
416        self.whether_to_add_comma()?;
417        value.serialize(&mut **self)
418    }
419
420    fn end(self) -> Result<(), Error> {
421        self.element_num.pop();
422        self.add_another_half(b"]}")
423    }
424}
425
426// Some "Serialize" types cannot hold both keys and values
427// in memory, so the "SerializeMap" implementation needs to
428// support "serialize_key" and "serialize_value" respectively.
429//
430// There is a third optional method on the `SerializeMap` trait.
431// The 'serialize_entry' method allows the serializer to be optimized
432// for cases where both keys and values are available. In JSON, it doesn't
433// make a difference so the default behavior for `serialize_entry` is fine.
434impl<'a, W: std::io::Write> ser::SerializeMap for &'a mut Serializer<W> {
435    type Ok = ();
436    type Error = Error;
437
438    // The Serde data model allows map keys to be any serializable type. JSON
439    // only allows string keys, so if the key is serialized to something other than a string,
440    // the following implementation will produce invalid JSON.
441    fn serialize_key<T>(&mut self, key: &T) -> Result<(), Error>
442    where
443        T: ?Sized + Serialize,
444    {
445        self.whether_to_add_comma()?;
446        key.serialize(&mut **self)
447    }
448
449    // It makes no difference whether the colon is printed at
450    // the end of 'serialize_key' or at the beginning of 'serialize_value'.
451    // Here we choose to print at the beginning of 'serialize_value'.
452    fn serialize_value<T>(&mut self, value: &T) -> Result<(), Error>
453    where
454        T: ?Sized + Serialize,
455    {
456        self.writer.write_all(b":")?;
457        value.serialize(&mut **self)
458    }
459
460    fn end(self) -> Result<(), Error> {
461        self.add_another_half(b"}")
462    }
463}
464
465// A structure is like a map where the keys are restricted to a compile-time constant string.
466impl<'a, W: std::io::Write> ser::SerializeStruct for &'a mut Serializer<W> {
467    type Ok = ();
468    type Error = Error;
469
470    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
471    where
472        T: ?Sized + Serialize,
473    {
474        self.whether_to_add_comma()?;
475        key.serialize(&mut **self)?;
476        self.writer.write_all(b":")?;
477        value.serialize(&mut **self)
478    }
479
480    fn end(self) -> Result<(), Error> {
481        self.element_num.pop();
482        self.add_another_half(b"}")
483    }
484}
485
486// Similar to 'SerializeTupleVariant', the 'end' method here is responsible for
487// closing two curly braces opened by 'serialize_struct_variant'.
488impl<'a, W: std::io::Write> ser::SerializeStructVariant for &'a mut Serializer<W> {
489    type Ok = ();
490    type Error = Error;
491
492    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
493    where
494        T: ?Sized + Serialize,
495    {
496        self.whether_to_add_comma()?;
497        key.serialize(&mut **self)?;
498        self.writer.write_all(b":")?;
499        value.serialize(&mut **self)
500    }
501
502    fn end(self) -> Result<(), Error> {
503        self.element_num.pop();
504        self.add_another_half(b"}}")
505    }
506}
507
508#[cfg(test)]
509mod ut_serializer {
510    use super::*;
511    use std::collections::HashMap;
512
513    /// UT test to serialize simple types.
514    ///
515    /// # Title
516    /// ut_serialize_simple
517    ///
518    /// # Brief
519    /// 1.Uses Serializer::to_string method to serialize simple types.
520    /// 2.Checks if the test results are correct.
521    #[test]
522    fn ut_serialize_simple() {
523        let value: Option<u32> = None;
524        let expected = "null";
525        assert_eq!(to_string(&value).unwrap(), expected);
526
527        let value: Option<u32> = Some(123);
528        let expected = "123";
529        assert_eq!(to_string(&value).unwrap(), expected);
530
531        let value = true;
532        let expected = "true";
533        assert_eq!(to_string(&value).unwrap(), expected);
534
535        let value: i8 = 123;
536        let expected = "123";
537        assert_eq!(to_string(&value).unwrap(), expected);
538
539        let value: i16 = 123;
540        let expected = "123";
541        assert_eq!(to_string(&value).unwrap(), expected);
542
543        let value: i32 = 123;
544        let expected = "123";
545        assert_eq!(to_string(&value).unwrap(), expected);
546
547        let value: i64 = 123;
548        let expected = "123";
549        assert_eq!(to_string(&value).unwrap(), expected);
550
551        let value: u8 = 123;
552        let expected = "123";
553        assert_eq!(to_string(&value).unwrap(), expected);
554
555        let value: u16 = 123;
556        let expected = "123";
557        assert_eq!(to_string(&value).unwrap(), expected);
558
559        let value: u32 = 123;
560        let expected = "123";
561        assert_eq!(to_string(&value).unwrap(), expected);
562
563        let value: u64 = 123;
564        let expected = "123";
565        assert_eq!(to_string(&value).unwrap(), expected);
566
567        let value: f32 = 1.0;
568        let expected = "1.0";
569        assert_eq!(to_string(&value).unwrap(), expected);
570
571        let value: f64 = 1.0;
572        let expected = "1.0";
573        assert_eq!(to_string(&value).unwrap(), expected);
574
575        let value = "abc";
576        let expected = "\"abc\"";
577        assert_eq!(to_string(&value).unwrap(), expected);
578
579        let value = b"abc";
580        let expected = "[97,98,99]";
581        assert_eq!(to_string(&value).unwrap(), expected);
582    }
583
584    /// UT test to serialize struct
585    ///
586    /// # Title
587    /// ut_serialize_struct
588    ///
589    /// # Brief
590    /// 1.Uses Serializer::to_string method to serialize struct.
591    /// 2.Checks if the test results are correct.
592    #[test]
593    fn ut_serialize_struct() {
594        #[derive(Serialize)]
595        struct TestUnit;
596        let test = TestUnit;
597        let expected = "null";
598        assert_eq!(to_string(&test).unwrap(), expected);
599
600        #[derive(Serialize)]
601        struct TestNewtype(u32);
602        let test = TestNewtype(123);
603        let expected = "123";
604        assert_eq!(to_string(&test).unwrap(), expected);
605
606        #[derive(Serialize)]
607        struct TestTuple(u32, u32, bool);
608        let test = TestTuple(123, 321, true);
609        let expected = "[123,321,true]";
610        assert_eq!(to_string(&test).unwrap(), expected);
611
612        #[derive(Serialize)]
613        struct Test {
614            int: u32,
615            seq: Vec<&'static str>,
616            tup: (i32, i32, i32),
617        }
618
619        let test = Test {
620            int: 1,
621            seq: vec!["a", "b"],
622            tup: (1, 2, 3),
623        };
624        let expected = r#"{"int":1,"seq":["a","b"],"tup":[1,2,3]}"#;
625        assert_eq!(to_string(&test).unwrap(), expected);
626    }
627
628    /// UT test to serialize enum
629    ///
630    /// # Title
631    /// ut_serialize_enum
632    ///
633    /// # Brief
634    /// 1.Uses Serializer::to_string method to serialize enum.
635    /// 2.Checks if the test results are correct.
636    #[test]
637    fn ut_serialize_enum() {
638        #[derive(Serialize)]
639        enum E {
640            Newtype(i32),
641            Unit,
642            Struct { a: u32 },
643            Tuple(u32, u32),
644        }
645
646        let n = E::Newtype(-1);
647        let expected = r#"{"Newtype":-1}"#;
648        assert_eq!(to_string(&n).unwrap(), expected);
649
650        let u = E::Unit;
651        let expected = r#""Unit""#;
652        assert_eq!(to_string(&u).unwrap(), expected);
653
654        let s = E::Struct { a: 10 };
655        let expected = r#"{"Struct":{"a":10}}"#;
656        assert_eq!(to_string(&s).unwrap(), expected);
657
658        let t = E::Tuple(100, 200);
659        let expected = r#"{"Tuple":[100,200]}"#;
660        assert_eq!(to_string(&t).unwrap(), expected);
661    }
662
663    /// UT test to serialize string
664    ///
665    /// # Title
666    /// ut_serialize_string
667    ///
668    /// # Brief
669    /// 1.Uses Serializer::to_string method to serialize string.
670    /// 2.Checks if the test results are correct.
671    #[test]
672    fn ut_serialize_string() {
673        let ch = 't';
674        let expected = r#""t""#;
675        assert_eq!(to_string(&ch).unwrap(), expected);
676
677        let value = String::from("test string.");
678        let expected = r#""test string.""#;
679        assert_eq!(to_string(&value).unwrap(), expected);
680
681        #[cfg(not(feature = "ascii_only"))]
682        {
683            let ch = '中';
684            let expected = r#""\u4e2d""#;
685            assert_eq!(to_string(&ch).unwrap(), expected);
686
687            let value = String::from("中文测试字符串");
688            let expected = r#""\u4e2d\u6587\u6d4b\u8bd5\u5b57\u7b26\u4e32""#;
689            assert_eq!(to_string(&value).unwrap(), expected);
690        }
691    }
692
693    /// UT test to serializer object
694    ///
695    /// # Title
696    /// ut_serialize_object
697    ///
698    /// # Brief
699    /// 1.Uses Serializer::to_string method to serialize object.
700    /// 2.Checks if the test results are correct.
701    #[test]
702    fn ut_serialize_object() {
703        let mut hash = HashMap::new();
704        hash.insert("apple", 1);
705        let expected = r#"{"apple":1}"#;
706        assert_eq!(to_string(&hash).unwrap(), expected);
707        hash.insert("banana", 2);
708        assert!(to_string(&hash).is_ok());
709    }
710}
711