musli_json/en/
mod.rs

1mod array_encoder;
2use self::array_encoder::JsonArrayEncoder;
3
4mod object_encoder;
5use self::object_encoder::JsonObjectEncoder;
6
7mod object_key_encoder;
8use self::object_key_encoder::JsonObjectKeyEncoder;
9
10mod object_pair_encoder;
11use self::object_pair_encoder::JsonObjectPairEncoder;
12
13mod variant_encoder;
14use self::variant_encoder::JsonVariantEncoder;
15
16use core::fmt;
17
18use musli::en::{Encoder, SequenceEncoder};
19use musli::hint::{MapHint, SequenceHint};
20use musli::{Context, Encode};
21use musli_utils::Writer;
22
23/// A JSON encoder for Müsli.
24pub(crate) struct JsonEncoder<'a, W, C: ?Sized> {
25    cx: &'a C,
26    writer: W,
27}
28
29impl<'a, W, C: ?Sized> JsonEncoder<'a, W, C> {
30    /// Construct a new fixed width message encoder.
31    #[inline]
32    pub(crate) fn new(cx: &'a C, writer: W) -> Self {
33        Self { cx, writer }
34    }
35}
36
37#[musli::encoder]
38impl<'a, C, W> Encoder for JsonEncoder<'a, W, C>
39where
40    W: Writer,
41    C: ?Sized + Context,
42{
43    type Cx = C;
44    type Error = C::Error;
45    type Ok = ();
46    type Mode = C::Mode;
47    type WithContext<'this, U> = JsonEncoder<'this, W, U> where U: 'this + Context;
48    type EncodePack = JsonArrayEncoder<'a, W, C>;
49    type EncodeSome = Self;
50    type EncodeSequence = JsonArrayEncoder<'a, W, C>;
51    type EncodeMap = JsonObjectEncoder<'a, W, C>;
52    type EncodeMapEntries = JsonObjectEncoder<'a, W, C>;
53    type EncodeVariant = JsonVariantEncoder<'a, W, C>;
54    type EncodeSequenceVariant = JsonArrayEncoder<'a, W, C>;
55    type EncodeMapVariant = JsonObjectEncoder<'a, W, C>;
56
57    #[inline]
58    fn cx(&self) -> &C {
59        self.cx
60    }
61
62    #[inline]
63    fn with_context<U>(self, cx: &U) -> Result<Self::WithContext<'_, U>, C::Error>
64    where
65        U: Context,
66    {
67        Ok(JsonEncoder::new(cx, self.writer))
68    }
69
70    #[inline]
71    fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72        write!(f, "value that can be encoded to JSON")
73    }
74
75    #[inline]
76    fn encode<T>(self, value: T) -> Result<Self::Ok, Self::Error>
77    where
78        T: Encode<Self::Mode>,
79    {
80        value.encode(self.cx, self)
81    }
82
83    #[inline]
84    fn encode_unit(mut self) -> Result<Self::Ok, C::Error> {
85        self.writer.write_bytes(self.cx, b"null")
86    }
87
88    #[inline]
89    fn encode_bool(mut self, value: bool) -> Result<Self::Ok, C::Error> {
90        self.writer
91            .write_bytes(self.cx, if value { b"true" } else { b"false" })
92    }
93
94    #[inline]
95    fn encode_char(mut self, value: char) -> Result<Self::Ok, C::Error> {
96        encode_string(
97            self.cx,
98            self.writer.borrow_mut(),
99            value.encode_utf8(&mut [0, 0, 0, 0]).as_bytes(),
100        )
101    }
102
103    #[inline]
104    fn encode_u8(mut self, value: u8) -> Result<Self::Ok, C::Error> {
105        let mut buffer = itoa::Buffer::new();
106        self.writer
107            .write_bytes(self.cx, buffer.format(value).as_bytes())
108    }
109
110    #[inline]
111    fn encode_u16(mut self, value: u16) -> Result<Self::Ok, C::Error> {
112        let mut buffer = itoa::Buffer::new();
113        self.writer
114            .write_bytes(self.cx, buffer.format(value).as_bytes())
115    }
116
117    #[inline]
118    fn encode_u32(mut self, value: u32) -> Result<Self::Ok, C::Error> {
119        let mut buffer = itoa::Buffer::new();
120        self.writer
121            .write_bytes(self.cx, buffer.format(value).as_bytes())
122    }
123
124    #[inline]
125    fn encode_u64(mut self, value: u64) -> Result<Self::Ok, C::Error> {
126        let mut buffer = itoa::Buffer::new();
127        self.writer
128            .write_bytes(self.cx, buffer.format(value).as_bytes())
129    }
130
131    #[inline]
132    fn encode_u128(mut self, value: u128) -> Result<Self::Ok, C::Error> {
133        let mut buffer = itoa::Buffer::new();
134        self.writer
135            .write_bytes(self.cx, buffer.format(value).as_bytes())
136    }
137
138    #[inline]
139    fn encode_i8(mut self, value: i8) -> Result<Self::Ok, C::Error> {
140        let mut buffer = itoa::Buffer::new();
141        self.writer
142            .write_bytes(self.cx, buffer.format(value).as_bytes())
143    }
144
145    #[inline]
146    fn encode_i16(mut self, value: i16) -> Result<Self::Ok, C::Error> {
147        let mut buffer = itoa::Buffer::new();
148        self.writer
149            .write_bytes(self.cx, buffer.format(value).as_bytes())
150    }
151
152    #[inline]
153    fn encode_i32(mut self, value: i32) -> Result<Self::Ok, C::Error> {
154        let mut buffer = itoa::Buffer::new();
155        self.writer
156            .write_bytes(self.cx, buffer.format(value).as_bytes())
157    }
158
159    #[inline]
160    fn encode_i64(mut self, value: i64) -> Result<Self::Ok, C::Error> {
161        let mut buffer = itoa::Buffer::new();
162        self.writer
163            .write_bytes(self.cx, buffer.format(value).as_bytes())
164    }
165
166    #[inline]
167    fn encode_i128(mut self, value: i128) -> Result<Self::Ok, C::Error> {
168        let mut buffer = itoa::Buffer::new();
169        self.writer
170            .write_bytes(self.cx, buffer.format(value).as_bytes())
171    }
172
173    #[inline]
174    fn encode_usize(mut self, value: usize) -> Result<Self::Ok, C::Error> {
175        let mut buffer = itoa::Buffer::new();
176        self.writer
177            .write_bytes(self.cx, buffer.format(value).as_bytes())
178    }
179
180    #[inline]
181    fn encode_isize(mut self, value: isize) -> Result<Self::Ok, C::Error> {
182        let mut buffer = itoa::Buffer::new();
183        self.writer
184            .write_bytes(self.cx, buffer.format(value).as_bytes())
185    }
186
187    #[inline]
188    fn encode_f32(mut self, value: f32) -> Result<Self::Ok, C::Error> {
189        let mut buffer = ryu::Buffer::new();
190        self.writer
191            .write_bytes(self.cx, buffer.format(value).as_bytes())
192    }
193
194    #[inline]
195    fn encode_f64(mut self, value: f64) -> Result<Self::Ok, C::Error> {
196        let mut buffer = ryu::Buffer::new();
197        self.writer
198            .write_bytes(self.cx, buffer.format(value).as_bytes())
199    }
200
201    #[inline]
202    fn encode_array<const N: usize>(self, bytes: &[u8; N]) -> Result<Self::Ok, C::Error> {
203        self.encode_bytes(bytes)
204    }
205
206    #[inline]
207    fn encode_bytes(mut self, bytes: &[u8]) -> Result<Self::Ok, C::Error> {
208        let mut buf = itoa::Buffer::new();
209        let mut it = bytes.iter();
210        let last = it.next_back();
211
212        self.writer.write_byte(self.cx, b'[')?;
213
214        for b in it {
215            self.writer
216                .write_bytes(self.cx, buf.format(*b).as_bytes())?;
217            self.writer.write_byte(self.cx, b',')?;
218        }
219
220        if let Some(b) = last {
221            self.writer
222                .write_bytes(self.cx, buf.format(*b).as_bytes())?;
223        }
224
225        self.writer.write_byte(self.cx, b']')?;
226        Ok(())
227    }
228
229    #[inline]
230    fn encode_bytes_vectored<I>(self, _: usize, vectors: I) -> Result<Self::Ok, C::Error>
231    where
232        I: IntoIterator,
233        I::Item: AsRef<[u8]>,
234    {
235        let mut seq = JsonArrayEncoder::new(self.cx, self.writer)?;
236
237        for bb in vectors {
238            for &b in bb.as_ref() {
239                seq.push(b)?;
240            }
241        }
242
243        seq.finish_sequence()
244    }
245
246    #[inline]
247    fn encode_string(mut self, string: &str) -> Result<Self::Ok, C::Error> {
248        encode_string(self.cx, self.writer.borrow_mut(), string.as_bytes())
249    }
250
251    #[inline]
252    fn collect_string<T>(self, value: &T) -> Result<Self::Ok, <Self::Cx as Context>::Error>
253    where
254        T: ?Sized + fmt::Display,
255    {
256        let buf = self.cx.collect_string(value)?;
257        self.encode_string(buf.as_ref())
258    }
259
260    #[inline]
261    fn encode_some(self) -> Result<Self::EncodeSome, C::Error> {
262        Ok(self)
263    }
264
265    #[inline]
266    fn encode_none(self) -> Result<Self::Ok, C::Error> {
267        self.encode_unit()
268    }
269
270    #[inline]
271    fn encode_pack(self) -> Result<Self::EncodePack, C::Error> {
272        JsonArrayEncoder::new(self.cx, self.writer)
273    }
274
275    #[inline]
276    fn encode_sequence(self, _: &SequenceHint) -> Result<Self::EncodeSequence, C::Error> {
277        JsonArrayEncoder::new(self.cx, self.writer)
278    }
279
280    #[inline]
281    fn encode_map(self, _: &MapHint) -> Result<Self::EncodeMap, C::Error> {
282        JsonObjectEncoder::new(self.cx, self.writer)
283    }
284
285    #[inline]
286    fn encode_map_entries(self, _: &MapHint) -> Result<Self::EncodeMapEntries, C::Error> {
287        JsonObjectEncoder::new(self.cx, self.writer)
288    }
289
290    #[inline]
291    fn encode_variant(self) -> Result<Self::EncodeVariant, C::Error> {
292        JsonVariantEncoder::new(self.cx, self.writer)
293    }
294
295    #[inline]
296    fn encode_sequence_variant<T>(
297        mut self,
298        tag: &T,
299        _: &SequenceHint,
300    ) -> Result<Self::EncodeSequenceVariant, C::Error>
301    where
302        T: ?Sized + Encode<C::Mode>,
303    {
304        self.writer.write_byte(self.cx, b'{')?;
305        JsonObjectKeyEncoder::new(self.cx, self.writer.borrow_mut()).encode(tag)?;
306        self.writer.write_byte(self.cx, b':')?;
307        JsonArrayEncoder::with_end(self.cx, self.writer, b"]}")
308    }
309
310    #[inline]
311    fn encode_map_variant<T>(
312        mut self,
313        tag: &T,
314        _: &MapHint,
315    ) -> Result<Self::EncodeMapVariant, C::Error>
316    where
317        T: ?Sized + Encode<C::Mode>,
318    {
319        self.writer.write_byte(self.cx, b'{')?;
320        JsonObjectKeyEncoder::new(self.cx, self.writer.borrow_mut()).encode(tag)?;
321        self.writer.write_byte(self.cx, b':')?;
322        JsonObjectEncoder::with_end(self.cx, self.writer, b"}}")
323    }
324}
325
326/// Encode a sequence of chars as a string.
327#[inline]
328fn encode_string<C, W>(cx: &C, mut w: W, bytes: &[u8]) -> Result<(), C::Error>
329where
330    C: ?Sized + Context,
331    W: Writer,
332{
333    w.write_byte(cx, b'"')?;
334
335    let mut start = 0;
336
337    for (i, &b) in bytes.iter().enumerate() {
338        let escape = ESCAPE[b as usize];
339
340        if escape == 0 {
341            continue;
342        }
343
344        if start < i {
345            w.write_bytes(cx, &bytes[start..i])?;
346        }
347
348        write_escape(cx, w.borrow_mut(), escape, b)?;
349        start = i + 1;
350    }
351
352    if start != bytes.len() {
353        w.write_bytes(cx, &bytes[start..])?;
354    }
355
356    w.write_byte(cx, b'"')?;
357    Ok(())
358}
359
360// Parts below copied from serde-json under the MIT license:
361//
362// https://github.com/serde-rs/json
363
364const BB: u8 = b'b'; // \x08
365const TT: u8 = b't'; // \x09
366const NN: u8 = b'n'; // \x0A
367const FF: u8 = b'f'; // \x0C
368const RR: u8 = b'r'; // \x0D
369const QU: u8 = b'"'; // \x22
370const BS: u8 = b'\\'; // \x5C
371const UU: u8 = b'u'; // \x00...\x1F except the ones above
372const __: u8 = 0;
373
374// Lookup table of escape sequences. A value of b'x' at index i means that byte
375// i is escaped as "\x" in JSON. A value of 0 means that byte i is not escaped.
376static ESCAPE: [u8; 256] = [
377    //   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
378    UU, UU, UU, UU, UU, UU, UU, UU, BB, TT, NN, UU, FF, RR, UU, UU, // 0
379    UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, // 1
380    __, __, QU, __, __, __, __, __, __, __, __, __, __, __, __, __, // 2
381    __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 3
382    __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 4
383    __, __, __, __, __, __, __, __, __, __, __, __, BS, __, __, __, // 5
384    __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 6
385    __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 7
386    __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 8
387    __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 9
388    __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // A
389    __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // B
390    __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // C
391    __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // D
392    __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // E
393    __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // F
394];
395
396// Hex digits.
397static HEX_DIGITS: [u8; 16] = *b"0123456789abcdef";
398
399fn write_escape<C, W>(cx: &C, mut writer: W, escape: u8, byte: u8) -> Result<(), C::Error>
400where
401    C: ?Sized + Context,
402    W: Writer,
403{
404    let s = match escape {
405        BB => b"\\b",
406        TT => b"\\t",
407        NN => b"\\n",
408        FF => b"\\f",
409        RR => b"\\r",
410        QU => b"\\\"",
411        BS => b"\\\\",
412        UU => {
413            let bytes = &[
414                b'\\',
415                b'u',
416                b'0',
417                b'0',
418                HEX_DIGITS[(byte >> 4) as usize],
419                HEX_DIGITS[(byte & 0xF) as usize],
420            ];
421            return writer.write_bytes(cx, bytes);
422        }
423        _ => unreachable!(),
424    };
425
426    writer.write_bytes(cx, s)
427}