lib_contra/serialize/
json.rs

1use std::io;
2use std::mem::size_of;
3
4use crate::error::{AnyError, IoResult, SuccessResult};
5use crate::formatter::WriteFormatter;
6
7use crate::position::Position;
8use crate::serialize::{Serialize, Serializer};
9
10pub trait IntoJson {
11    fn to_json(&self) -> Result<String, AnyError>;
12}
13
14impl<S: Serialize> IntoJson for S {
15    fn to_json(&self) -> Result<String, AnyError> {
16        let mut buffer: Vec<u8> = Vec::with_capacity(size_of::<S>());
17        let formatter = PrettyJsonFormatter::new("\t".to_string());
18        let mut serializer = JsonSerializer::new(formatter, &mut buffer);
19
20        self.serialize(&mut serializer, &Position::Closing)?;
21
22        unsafe { Ok(String::from_utf8_unchecked(buffer)) }
23    }
24}
25
26pub struct JsonSerializer<'w, W: io::Write, F: WriteFormatter<W>> {
27    write: &'w mut W,
28    formatter: F,
29}
30
31impl<'w, W: io::Write, F: WriteFormatter<W>> JsonSerializer<'w, W, F> {
32    pub fn new(formatter: F, write: &'w mut W) -> Self {
33        Self { formatter, write }
34    }
35}
36
37macro_rules! impl_serialize_primitive {
38    ($type: ident, $ser_func: ident, $for_func: ident) => {
39        fn $ser_func(&mut self, value: &$type) -> SuccessResult {
40            self.formatter.$for_func(self.write, value)?;
41            Ok(())
42        }
43    };
44}
45
46impl<'w, W: io::Write, F: WriteFormatter<W>> Serializer for JsonSerializer<'w, W, F> {
47    fn begin_struct(&mut self, name: &str, fields: usize) -> SuccessResult {
48        self.formatter
49            .write_struct_begin(self.write, name, fields)?;
50        Ok(())
51    }
52
53    fn end_struct(&mut self, name: &str) -> SuccessResult {
54        self.formatter.write_struct_end(self.write, name)?;
55        Ok(())
56    }
57
58    fn serialize_field<V: crate::serialize::Serialize>(
59        &mut self,
60        identifier: &str,
61        value: &V,
62        pos: &Position,
63    ) -> SuccessResult {
64        self.formatter.write_field_assignnment_begin(self.write)?;
65        self.formatter.write_field_key(self.write, identifier)?;
66        self.formatter
67            .write_field_assignnment_operator(self.write)?;
68        value.serialize(self, &pos)?;
69        self.formatter
70            .write_field_assignnment_end(self.write, &pos)?;
71        Ok(())
72    }
73
74    fn serialize_value<V: crate::serialize::Serialize>(
75        &mut self,
76        value: &V,
77        pos: &Position,
78    ) -> SuccessResult {
79        value.serialize(self, pos)?;
80        Ok(())
81    }
82
83    fn begin_collection(&mut self, name: &str, size: usize) -> SuccessResult {
84        self.formatter
85            .write_collection_begin(self.write, name, size)?;
86        Ok(())
87    }
88
89    fn end_collection(&mut self, name: &str) -> SuccessResult {
90        self.formatter.write_collection_end(self.write, name)?;
91        Ok(())
92    }
93
94    fn serialize_item<V: Serialize>(
95        &mut self,
96        _i: usize,
97        item: &V,
98        pos: &Position,
99    ) -> SuccessResult {
100        self.serialize_value(item, pos)
101    }
102
103    impl_serialize_primitive!(i8, serialize_i8, write_i8);
104    impl_serialize_primitive!(i16, serialize_i16, write_i16);
105    impl_serialize_primitive!(i32, serialize_i32, write_i32);
106    impl_serialize_primitive!(i64, serialize_i64, write_i64);
107    impl_serialize_primitive!(i128, serialize_i128, write_i128);
108    impl_serialize_primitive!(u8, serialize_u8, write_u8);
109    impl_serialize_primitive!(u16, serialize_u16, write_u16);
110    impl_serialize_primitive!(u32, serialize_u32, write_u32);
111    impl_serialize_primitive!(u64, serialize_u64, write_u64);
112    impl_serialize_primitive!(u128, serialize_u128, write_u128);
113    impl_serialize_primitive!(f32, serialize_f32, write_f32);
114    impl_serialize_primitive!(f64, serialize_f64, write_f64);
115    impl_serialize_primitive!(usize, serialize_usize, write_usize);
116    impl_serialize_primitive!(isize, serialize_isize, write_isize);
117    impl_serialize_primitive!(str, serialize_str, write_str);
118}
119
120pub struct PrettyJsonFormatter {
121    ident_sym: String,
122    ident_num: usize,
123}
124
125impl PrettyJsonFormatter {
126    pub fn new(sym: String) -> Self {
127        Self {
128            ident_sym: sym,
129            ident_num: 0,
130        }
131    }
132
133    fn increase_ident(&mut self) {
134        self.ident_num += 1;
135    }
136
137    fn decrease_ident(&mut self) {
138        self.ident_num -= 1;
139    }
140
141    fn write_ident<W: io::Write>(&mut self, write: &mut W) -> IoResult {
142        write.write_all(self.ident_sym.repeat(self.ident_num).as_bytes())?;
143        Ok(())
144    }
145
146    fn write_unescaped_string<W: io::Write>(&mut self, write: &mut W, value: &str) -> IoResult {
147        write.write_all(value.as_bytes())?;
148        Ok(())
149    }
150
151    fn write_escaped_string<W: io::Write>(&mut self, write: &mut W, value: &str) -> IoResult {
152        write.write_fmt(format_args!("\"{}\"", value))?;
153        Ok(())
154    }
155
156    fn write_line_break<W: io::Write>(&mut self, write: &mut W) -> IoResult {
157        // ToDo: Make linebreak platform independant
158        write.write_all(b"\n")?;
159        Ok(())
160    }
161
162    fn write_whitespace<W: io::Write>(&mut self, write: &mut W, n: usize) -> IoResult {
163        write.write_all(" ".repeat(n).as_bytes())?;
164        Ok(())
165    }
166
167    fn write_seperator<W: io::Write>(&mut self, write: &mut W) -> IoResult {
168        write.write_all(b",")?;
169        Ok(())
170    }
171}
172
173macro_rules! impl_write_primitive {
174    ($type: ident, $ser_func: ident) => {
175        fn $ser_func(&mut self, write: &mut W, value: &$type) -> IoResult {
176            self.write_escaped_string(write, &value.to_string())?;
177            Ok(())
178        }
179    };
180}
181
182impl<W: io::Write> WriteFormatter<W> for PrettyJsonFormatter {
183    fn write_struct_begin(&mut self, write: &mut W, _name: &str, _fields: usize) -> IoResult {
184        self.write_ident(write)?;
185        self.write_unescaped_string(write, "{")?;
186        self.write_line_break(write)?;
187        self.increase_ident();
188        Ok(())
189    }
190
191    fn write_struct_end(&mut self, write: &mut W, _name: &str) -> IoResult {
192        self.decrease_ident();
193        self.write_ident(write)?;
194        self.write_unescaped_string(write, "}")?;
195        Ok(())
196    }
197
198    fn write_field_assignnment_begin(&mut self, write: &mut W) -> IoResult {
199        self.write_ident(write)?;
200        Ok(())
201    }
202
203    fn write_field_key(&mut self, write: &mut W, name: &str) -> IoResult {
204        self.write_escaped_string(write, name)?;
205        self.write_whitespace(write, 1)?;
206        Ok(())
207    }
208
209    fn write_field_assignnment_operator(&mut self, write: &mut W) -> IoResult {
210        self.write_unescaped_string(write, ":")?;
211        self.write_whitespace(write, 1)?;
212        Ok(())
213    }
214
215    fn write_field_assignnment_end(&mut self, write: &mut W, pos: &Position) -> IoResult {
216        match pos {
217            Position::Trailing => self.write_seperator(write)?,
218            Position::Closing => (),
219        }
220        self.write_line_break(write)?;
221        Ok(())
222    }
223
224    fn write_collection_begin(&mut self, write: &mut W, _name: &str, _size: usize) -> IoResult {
225        write.write_all(b"[")?;
226        self.write_line_break(write)?;
227        Ok(())
228    }
229
230    fn write_collection_end(&mut self, write: &mut W, _name: &str) -> IoResult {
231        write.write_all(b"]")?;
232        Ok(())
233    }
234
235    impl_write_primitive!(i8, write_i8);
236    impl_write_primitive!(i16, write_i16);
237    impl_write_primitive!(i32, write_i32);
238    impl_write_primitive!(i64, write_i64);
239    impl_write_primitive!(i128, write_i128);
240    impl_write_primitive!(u8, write_u8);
241    impl_write_primitive!(u16, write_u16);
242    impl_write_primitive!(u32, write_u32);
243    impl_write_primitive!(u64, write_u64);
244    impl_write_primitive!(u128, write_u128);
245    impl_write_primitive!(f32, write_f32);
246    impl_write_primitive!(f64, write_f64);
247    impl_write_primitive!(usize, write_usize);
248    impl_write_primitive!(isize, write_isize);
249    impl_write_primitive!(str, write_str);
250}