musli_json/en/
object_encoder.rs

1use musli::en::{EntriesEncoder, MapEncoder};
2use musli::Context;
3use musli_utils::Writer;
4
5use super::{JsonEncoder, JsonObjectKeyEncoder, JsonObjectPairEncoder};
6
7/// An object encoder for JSON.
8pub(crate) struct JsonObjectEncoder<'a, W, C: ?Sized> {
9    cx: &'a C,
10    len: usize,
11    end: &'static [u8],
12    writer: W,
13}
14
15impl<'a, W, C> JsonObjectEncoder<'a, W, C>
16where
17    W: Writer,
18    C: ?Sized + Context,
19{
20    #[inline]
21    pub(super) fn new(cx: &'a C, writer: W) -> Result<Self, C::Error> {
22        Self::with_end(cx, writer, b"}")
23    }
24
25    #[inline]
26    pub(super) fn with_end(cx: &'a C, mut writer: W, end: &'static [u8]) -> Result<Self, C::Error> {
27        writer.write_byte(cx, b'{')?;
28
29        Ok(Self {
30            cx,
31            len: 0,
32            end,
33            writer,
34        })
35    }
36}
37
38impl<'a, W, C> MapEncoder for JsonObjectEncoder<'a, W, C>
39where
40    W: Writer,
41    C: ?Sized + Context,
42{
43    type Cx = C;
44    type Ok = ();
45    type EncodeEntry<'this> = JsonObjectPairEncoder<'a, W::Mut<'this>, C>
46    where
47        Self: 'this;
48
49    #[inline]
50    fn encode_entry(&mut self) -> Result<Self::EncodeEntry<'_>, C::Error> {
51        self.len += 1;
52
53        Ok(JsonObjectPairEncoder::new(
54            self.cx,
55            self.len == 1,
56            self.writer.borrow_mut(),
57        ))
58    }
59
60    #[inline]
61    fn finish_map(mut self) -> Result<Self::Ok, C::Error> {
62        self.writer.write_bytes(self.cx, self.end)
63    }
64}
65
66impl<'a, W, C> EntriesEncoder for JsonObjectEncoder<'a, W, C>
67where
68    W: Writer,
69    C: ?Sized + Context,
70{
71    type Cx = C;
72    type Ok = ();
73    type EncodeEntryKey<'this> = JsonObjectKeyEncoder<'a, W::Mut<'this>, C>
74    where
75        Self: 'this;
76    type EncodeEntryValue<'this> = JsonEncoder<'a, W::Mut<'this>, C> where Self: 'this;
77
78    #[inline]
79    fn encode_entry_key(&mut self) -> Result<Self::EncodeEntryKey<'_>, C::Error> {
80        if self.len > 0 {
81            self.writer.write_byte(self.cx, b',')?;
82        }
83
84        self.len += 1;
85        Ok(JsonObjectKeyEncoder::new(self.cx, self.writer.borrow_mut()))
86    }
87
88    #[inline]
89    fn encode_entry_value(&mut self) -> Result<Self::EncodeEntryValue<'_>, C::Error> {
90        self.writer.write_byte(self.cx, b':')?;
91        Ok(JsonEncoder::new(self.cx, self.writer.borrow_mut()))
92    }
93
94    #[inline]
95    fn finish_entries(mut self) -> Result<Self::Ok, C::Error> {
96        self.writer.write_byte(self.cx, b'}')
97    }
98}