compact binary serialization format with built-in compression
1use hateno::Tag;
2
3use crate::{Error, Result};
4
5use serde::{Serialize, ser};
6
7pub struct SerializeVec {
8 elements: Vec<Tag>,
9}
10
11impl SerializeVec {
12 pub fn new() -> Self {
13 Self {
14 elements: Vec::new(),
15 }
16 }
17
18 fn try_into_array(self) -> Tag {
19 if self.elements.is_empty() {
20 return Tag::new_list(self.elements);
21 }
22
23 let first_kind = self.elements[0].kind();
24 if !first_kind.valid_for_array_element() {
25 return Tag::new_list(self.elements);
26 }
27
28 if self.elements.iter().all(|tag| tag.kind() == first_kind) {
29 Tag::new_array(first_kind, self.elements)
30 } else {
31 Tag::new_list(self.elements)
32 }
33 }
34}
35
36impl ser::SerializeSeq for SerializeVec {
37 type Ok = Tag;
38 type Error = Error;
39
40 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
41 where
42 T: ?Sized + Serialize,
43 {
44 let tag = value.serialize(&mut super::TagSerializer)?;
45 self.elements.push(tag);
46 Ok(())
47 }
48
49 fn end(self) -> Result<Tag> {
50 Ok(self.try_into_array())
51 }
52}
53
54impl ser::SerializeTuple for SerializeVec {
55 type Ok = Tag;
56 type Error = Error;
57
58 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
59 where
60 T: ?Sized + Serialize,
61 {
62 ser::SerializeSeq::serialize_element(self, value)
63 }
64
65 fn end(self) -> Result<Tag> {
66 ser::SerializeSeq::end(self)
67 }
68}
69
70impl ser::SerializeTupleStruct for SerializeVec {
71 type Ok = Tag;
72 type Error = Error;
73
74 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
75 where
76 T: ?Sized + Serialize,
77 {
78 ser::SerializeSeq::serialize_element(self, value)
79 }
80
81 fn end(self) -> Result<Tag> {
82 ser::SerializeSeq::end(self)
83 }
84}
85
86pub struct SerializeTupleVariant {
87 variant: String,
88 elements: Vec<Tag>,
89}
90
91impl SerializeTupleVariant {
92 pub fn new(variant: &str) -> Self {
93 Self {
94 variant: variant.to_string(),
95 elements: Vec::new(),
96 }
97 }
98}
99
100impl ser::SerializeTupleVariant for SerializeTupleVariant {
101 type Ok = Tag;
102 type Error = Error;
103
104 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
105 where
106 T: ?Sized + Serialize,
107 {
108 let tag = value.serialize(&mut super::TagSerializer)?;
109 self.elements.push(tag);
110 Ok(())
111 }
112
113 fn end(self) -> Result<Tag> {
114 let key = Tag::new_string(self.variant);
115 let value = Tag::new_list(self.elements);
116 Ok(Tag::new_map(vec![(key, value)]))
117 }
118}
119
120pub struct SerializeMap {
121 entries: Vec<(Tag, Tag)>,
122 next_key: Option<Tag>,
123}
124
125impl SerializeMap {
126 pub fn new() -> Self {
127 Self {
128 entries: Vec::new(),
129 next_key: None,
130 }
131 }
132}
133
134impl ser::SerializeMap for SerializeMap {
135 type Ok = Tag;
136 type Error = Error;
137
138 fn serialize_key<T>(&mut self, key: &T) -> Result<()>
139 where
140 T: ?Sized + Serialize,
141 {
142 let key_tag = key.serialize(&mut super::TagSerializer)?;
143 self.next_key = Some(key_tag);
144 Ok(())
145 }
146
147 fn serialize_value<T>(&mut self, value: &T) -> Result<()>
148 where
149 T: ?Sized + Serialize,
150 {
151 let key = self.next_key.take().ok_or_else(|| {
152 Error::Custom(
153 "serialize_value called before serialize_key".to_string(),
154 )
155 })?;
156 let value_tag = value.serialize(&mut super::TagSerializer)?;
157 self.entries.push((key, value_tag));
158 Ok(())
159 }
160
161 fn end(self) -> Result<Tag> {
162 Ok(Tag::new_map(self.entries))
163 }
164}
165
166impl ser::SerializeStruct for SerializeMap {
167 type Ok = Tag;
168 type Error = Error;
169
170 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
171 where
172 T: ?Sized + Serialize,
173 {
174 let key_tag = Tag::new_string(key);
175 let value_tag = value.serialize(&mut super::TagSerializer)?;
176 self.entries.push((key_tag, value_tag));
177 Ok(())
178 }
179
180 fn end(self) -> Result<Tag> {
181 ser::SerializeMap::end(self)
182 }
183}
184
185pub struct SerializeStructVariant {
186 variant: String,
187 entries: Vec<(Tag, Tag)>,
188}
189
190impl SerializeStructVariant {
191 pub fn new(variant: &str) -> Self {
192 Self {
193 variant: variant.to_string(),
194 entries: Vec::new(),
195 }
196 }
197}
198
199impl ser::SerializeStructVariant for SerializeStructVariant {
200 type Ok = Tag;
201 type Error = Error;
202
203 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
204 where
205 T: ?Sized + Serialize,
206 {
207 let key_tag = Tag::new_string(key);
208 let value_tag = value.serialize(&mut super::TagSerializer)?;
209 self.entries.push((key_tag, value_tag));
210 Ok(())
211 }
212
213 fn end(self) -> Result<Tag> {
214 let variant_key = Tag::new_string(self.variant);
215 let variant_value = Tag::new_map(self.entries);
216 Ok(Tag::new_map(vec![(variant_key, variant_value)]))
217 }
218}