compact binary serialization format with built-in compression
1mod helper;
2
3use hateno::{Tag, TagKind};
4use serde::{Deserializer, de::Visitor};
5
6use crate::{Error, Result};
7
8pub struct TagDeserializer {
9 tag: Tag,
10}
11
12impl TagDeserializer {
13 pub fn new(tag: Tag) -> Self {
14 Self { tag }
15 }
16}
17
18impl<'de> Deserializer<'de> for &mut TagDeserializer {
19 type Error = Error;
20
21 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
22 where
23 V: Visitor<'de>,
24 {
25 match &self.tag {
26 Tag::Bool(v) => visitor.visit_bool(*v),
27 Tag::I8(v) => visitor.visit_i8(*v),
28 Tag::I16(v) => visitor.visit_i16(*v),
29 Tag::I32(v) => visitor.visit_i32(*v),
30 Tag::I64(v) => visitor.visit_i64(*v),
31 Tag::U8(v) => visitor.visit_u8(*v),
32 Tag::U16(v) => visitor.visit_u16(*v),
33 Tag::U32(v) => visitor.visit_u32(*v),
34 Tag::U64(v) => visitor.visit_u64(*v),
35 Tag::F32(v) => visitor.visit_f32(*v),
36 Tag::F64(v) => visitor.visit_f64(*v),
37 Tag::String(v) => visitor.visit_str(v),
38 Tag::List(v) => {
39 let seq = helper::ListAccess::new(v.clone());
40 visitor.visit_seq(seq)
41 }
42 Tag::Map(v) => {
43 let map = helper::MapAccess::new(v.clone());
44 visitor.visit_map(map)
45 }
46 Tag::Array(_, v) => {
47 let seq = helper::ListAccess::new(v.clone());
48 visitor.visit_seq(seq)
49 }
50 Tag::Option(_, opt) => match opt {
51 Some(tag) => {
52 let mut deserializer =
53 TagDeserializer::new((**tag).clone());
54 visitor.visit_some(&mut deserializer)
55 }
56 None => visitor.visit_none(),
57 },
58 Tag::Timestamp(dt) => visitor.visit_str(&dt.to_rfc3339()),
59 Tag::Uuid(uuid) => visitor.visit_str(&uuid.to_string()),
60 }
61 }
62
63 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
64 where
65 V: Visitor<'de>,
66 {
67 match &self.tag {
68 Tag::Bool(v) => visitor.visit_bool(*v),
69 _ => Err(Error::InvalidTagKind {
70 expected: "bool".to_string(),
71 found: self.tag.kind(),
72 }),
73 }
74 }
75
76 fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
77 where
78 V: Visitor<'de>,
79 {
80 match &self.tag {
81 Tag::I8(v) => visitor.visit_i8(*v),
82 _ => Err(Error::InvalidTagKind {
83 expected: "i8".to_string(),
84 found: self.tag.kind(),
85 }),
86 }
87 }
88
89 fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
90 where
91 V: Visitor<'de>,
92 {
93 match &self.tag {
94 Tag::I16(v) => visitor.visit_i16(*v),
95 _ => Err(Error::InvalidTagKind {
96 expected: "i16".to_string(),
97 found: self.tag.kind(),
98 }),
99 }
100 }
101
102 fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
103 where
104 V: Visitor<'de>,
105 {
106 match &self.tag {
107 Tag::I32(v) => visitor.visit_i32(*v),
108 _ => Err(Error::InvalidTagKind {
109 expected: "i32".to_string(),
110 found: self.tag.kind(),
111 }),
112 }
113 }
114
115 fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
116 where
117 V: Visitor<'de>,
118 {
119 match &self.tag {
120 Tag::I64(v) => visitor.visit_i64(*v),
121 _ => Err(Error::InvalidTagKind {
122 expected: "i64".to_string(),
123 found: self.tag.kind(),
124 }),
125 }
126 }
127
128 fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
129 where
130 V: Visitor<'de>,
131 {
132 match &self.tag {
133 Tag::U8(v) => visitor.visit_u8(*v),
134 _ => Err(Error::InvalidTagKind {
135 expected: "u8".to_string(),
136 found: self.tag.kind(),
137 }),
138 }
139 }
140
141 fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
142 where
143 V: Visitor<'de>,
144 {
145 match &self.tag {
146 Tag::U16(v) => visitor.visit_u16(*v),
147 _ => Err(Error::InvalidTagKind {
148 expected: "u16".to_string(),
149 found: self.tag.kind(),
150 }),
151 }
152 }
153
154 fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
155 where
156 V: Visitor<'de>,
157 {
158 match &self.tag {
159 Tag::U32(v) => visitor.visit_u32(*v),
160 _ => Err(Error::InvalidTagKind {
161 expected: "u32".to_string(),
162 found: self.tag.kind(),
163 }),
164 }
165 }
166
167 fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
168 where
169 V: Visitor<'de>,
170 {
171 match &self.tag {
172 Tag::U64(v) => visitor.visit_u64(*v),
173 _ => Err(Error::InvalidTagKind {
174 expected: "u64".to_string(),
175 found: self.tag.kind(),
176 }),
177 }
178 }
179
180 fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
181 where
182 V: Visitor<'de>,
183 {
184 match &self.tag {
185 Tag::F32(v) => visitor.visit_f32(*v),
186 _ => Err(Error::InvalidTagKind {
187 expected: "f32".to_string(),
188 found: self.tag.kind(),
189 }),
190 }
191 }
192
193 fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
194 where
195 V: Visitor<'de>,
196 {
197 match &self.tag {
198 Tag::F64(v) => visitor.visit_f64(*v),
199 _ => Err(Error::InvalidTagKind {
200 expected: "f64".to_string(),
201 found: self.tag.kind(),
202 }),
203 }
204 }
205
206 fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
207 where
208 V: Visitor<'de>,
209 {
210 match &self.tag {
211 Tag::String(v) => {
212 let mut chars = v.chars();
213 match (chars.next(), chars.next()) {
214 (Some(c), None) => visitor.visit_char(c),
215 _ => Err(Error::Custom(
216 "string is not a single character".to_string(),
217 )),
218 }
219 }
220 _ => Err(Error::InvalidTagKind {
221 expected: "string".to_string(),
222 found: self.tag.kind(),
223 }),
224 }
225 }
226
227 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
228 where
229 V: Visitor<'de>,
230 {
231 match &self.tag {
232 Tag::String(v) => visitor.visit_str(v),
233 _ => Err(Error::InvalidTagKind {
234 expected: "string".to_string(),
235 found: self.tag.kind(),
236 }),
237 }
238 }
239
240 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
241 where
242 V: Visitor<'de>,
243 {
244 self.deserialize_str(visitor)
245 }
246
247 fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
248 where
249 V: Visitor<'de>,
250 {
251 match &self.tag {
252 Tag::Array(TagKind::U8, elements) => {
253 let bytes: Result<Vec<u8>> = elements
254 .iter()
255 .map(|tag| match tag {
256 Tag::U8(b) => Ok(*b),
257 _ => Err(Error::InvalidTagKind {
258 expected: "u8".to_string(),
259 found: tag.kind(),
260 }),
261 })
262 .collect();
263 visitor.visit_bytes(&bytes?)
264 }
265 _ => Err(Error::InvalidTagKind {
266 expected: "byte array".to_string(),
267 found: self.tag.kind(),
268 }),
269 }
270 }
271
272 fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
273 where
274 V: Visitor<'de>,
275 {
276 self.deserialize_bytes(visitor)
277 }
278
279 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
280 where
281 V: Visitor<'de>,
282 {
283 match &self.tag {
284 Tag::Option(_, opt) => match opt {
285 Some(tag) => {
286 let mut deserializer =
287 TagDeserializer::new((**tag).clone());
288 visitor.visit_some(&mut deserializer)
289 }
290 None => visitor.visit_none(),
291 },
292 _ => visitor.visit_some(self),
293 }
294 }
295
296 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
297 where
298 V: Visitor<'de>,
299 {
300 match &self.tag {
301 Tag::List(elements) if elements.is_empty() => visitor.visit_unit(),
302 _ => Err(Error::InvalidTagKind {
303 expected: "unit".to_string(),
304 found: self.tag.kind(),
305 }),
306 }
307 }
308
309 fn deserialize_unit_struct<V>(
310 self,
311 _name: &'static str,
312 visitor: V,
313 ) -> Result<V::Value>
314 where
315 V: Visitor<'de>,
316 {
317 self.deserialize_unit(visitor)
318 }
319
320 fn deserialize_newtype_struct<V>(
321 self,
322 _name: &'static str,
323 visitor: V,
324 ) -> Result<V::Value>
325 where
326 V: Visitor<'de>,
327 {
328 visitor.visit_newtype_struct(self)
329 }
330
331 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
332 where
333 V: Visitor<'de>,
334 {
335 match &self.tag {
336 Tag::List(elements) => {
337 let seq = helper::ListAccess::new(elements.clone());
338 visitor.visit_seq(seq)
339 }
340 Tag::Array(_, elements) => {
341 let seq = helper::ListAccess::new(elements.clone());
342 visitor.visit_seq(seq)
343 }
344 _ => Err(Error::InvalidTagKind {
345 expected: "list or array".to_string(),
346 found: self.tag.kind(),
347 }),
348 }
349 }
350
351 fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
352 where
353 V: Visitor<'de>,
354 {
355 self.deserialize_seq(visitor)
356 }
357
358 fn deserialize_tuple_struct<V>(
359 self,
360 _name: &'static str,
361 _len: usize,
362 visitor: V,
363 ) -> Result<V::Value>
364 where
365 V: Visitor<'de>,
366 {
367 self.deserialize_seq(visitor)
368 }
369
370 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
371 where
372 V: Visitor<'de>,
373 {
374 match &self.tag {
375 Tag::Map(entries) => {
376 let map = helper::MapAccess::new(entries.clone());
377 visitor.visit_map(map)
378 }
379 _ => Err(Error::InvalidTagKind {
380 expected: "map".to_string(),
381 found: self.tag.kind(),
382 }),
383 }
384 }
385
386 fn deserialize_struct<V>(
387 self,
388 _name: &'static str,
389 _fields: &'static [&'static str],
390 visitor: V,
391 ) -> Result<V::Value>
392 where
393 V: Visitor<'de>,
394 {
395 self.deserialize_map(visitor)
396 }
397
398 fn deserialize_enum<V>(
399 self,
400 _name: &'static str,
401 _variants: &'static [&'static str],
402 visitor: V,
403 ) -> Result<V::Value>
404 where
405 V: Visitor<'de>,
406 {
407 match &self.tag {
408 Tag::String(variant) => visitor
409 .visit_enum(helper::UnitVariantAccess::new(variant.clone())),
410 Tag::Map(entries) if entries.len() == 1 => {
411 if let (Tag::String(variant), value) = &entries[0] {
412 let access = helper::VariantAccess::new(
413 variant.clone(),
414 value.clone(),
415 );
416 visitor.visit_enum(access)
417 } else {
418 Err(Error::InvalidTagKind {
419 expected: "enum variant".to_string(),
420 found: self.tag.kind(),
421 })
422 }
423 }
424 _ => Err(Error::InvalidTagKind {
425 expected: "enum".to_string(),
426 found: self.tag.kind(),
427 }),
428 }
429 }
430
431 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
432 where
433 V: Visitor<'de>,
434 {
435 self.deserialize_str(visitor)
436 }
437
438 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
439 where
440 V: Visitor<'de>,
441 {
442 visitor.visit_unit()
443 }
444}