microserde 0.3.0

Zero-dependency implementation of Serde
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
//! Deserialization traits.
//!
//! Deserialization in microserde works by handing out a visitor that borrows
//! the output slot into which data may be written through the methods of the
//! `Visitor` trait.
//!
//! A `Deserialize` impl provides an associated visitor type that holds a
//! `&mut Option<Self>` pointing at the output slot. Upon successful
//! deserialization the output object is written as `Some(T)` into that slot.
//!
//! ## Deserializing a primitive
//!
//! The visitor receives scalar values through the `scalar` method and matches
//! on the [`Scalar`] variants that the Rust type supports deserializing from.
//!
//! ```rust
//! use microserde::{Error, Result};
//! use microserde::de::{Deserialize, Scalar, Visitor};
//!
//! struct MyBoolean(bool);
//!
//! struct MyBooleanVisitor<'a> {
//!     out: &'a mut Option<MyBoolean>,
//! }
//!
//! // We match the scalar variants that our Rust type supports deserializing
//! // from, and write the result into the output slot.
//! //
//! // This method may perform validation and decide to return an error.
//! impl Visitor for MyBooleanVisitor<'_> {
//!     fn scalar(&mut self, s: &Scalar) -> Result<()> {
//!         let Scalar::Bool(b) = *s else {
//!             return Err(Error);
//!         };
//!         *self.out = Some(MyBoolean(b));
//!         Ok(())
//!     }
//! }
//!
//! impl Deserialize for MyBoolean {
//!     type Visitor<'a> = MyBooleanVisitor<'a>;
//!
//!     fn begin(out: &mut Option<Self>) -> Self::Visitor<'_> {
//!         MyBooleanVisitor { out }
//!     }
//! }
//! ```
//!
//! ## Deserializing a sequence
//!
//! In the case of a sequence (JSON array), the visitor method consumes the
//! visitor and returns a builder that can hand out visitors to write sequence
//! elements one element at a time.
//!
//! ```rust
//! use microserde::Result;
//! use microserde::de::{Deserialize, Seq, Visitor};
//! use std::mem;
//!
//! struct MyVec<T>(Vec<T>);
//!
//! struct MyVecVisitor<'a, T> {
//!     out: &'a mut Option<MyVec<T>>,
//! }
//!
//! impl<T: Deserialize> Visitor for MyVecVisitor<'_, T> {
//!     fn seq<'s>(self: Box<Self>) -> Result<Box<dyn Seq + 's>>
//!     where
//!         Self: 's,
//!     {
//!         Ok(Box::new(VecBuilder {
//!             out: self.out,
//!             vec: Vec::new(),
//!             element: None,
//!         }))
//!     }
//! }
//!
//! struct VecBuilder<'a, T: 'a> {
//!     // At the end, output will be written here.
//!     out: &'a mut Option<MyVec<T>>,
//!     // Previous elements are accumulated here.
//!     vec: Vec<T>,
//!     // Next element will be placed here.
//!     element: Option<T>,
//! }
//!
//! impl<'a, T: Deserialize> Seq for VecBuilder<'a, T> {
//!     fn element(&mut self) -> Result<Box<dyn Visitor + '_>> {
//!         // Free up the place by transfering the most recent element
//!         // into self.vec.
//!         self.vec.extend(self.element.take());
//!         // Hand out a visitor to write the next element.
//!         Ok(Box::new(Deserialize::begin(&mut self.element)))
//!     }
//!
//!     fn finish(&mut self) -> Result<()> {
//!         // Transfer the last element.
//!         self.vec.extend(self.element.take());
//!         // Move the output object into self.out.
//!         let vec = mem::replace(&mut self.vec, Vec::new());
//!         *self.out = Some(MyVec(vec));
//!         Ok(())
//!     }
//! }
//!
//! impl<T: Deserialize> Deserialize for MyVec<T> {
//!     type Visitor<'a>
//!         = MyVecVisitor<'a, T>
//!     where
//!         Self: 'a;
//!
//!     fn begin(out: &mut Option<Self>) -> Self::Visitor<'_> {
//!         MyVecVisitor { out }
//!     }
//! }
//! ```
//!
//! ## Deserializing a map or struct
//!
//! This code demonstrates what is generated for structs by
//! `#[derive(Deserialize)]`.
//!
//! ```rust
//! use microserde::Result;
//! use microserde::de::{Deserialize, Map, Visitor};
//!
//! // The struct that we would like to deserialize.
//! struct Demo {
//!     code: u32,
//!     message: String,
//! }
//!
//! struct DemoVisitor<'a> {
//!     out: &'a mut Option<Demo>,
//! }
//!
//! impl Visitor for DemoVisitor<'_> {
//!     fn map<'s>(self: Box<Self>) -> Result<Box<dyn Map + 's>>
//!     where
//!         Self: 's,
//!     {
//!         // Like for sequences, we produce a builder that can hand out
//!         // visitors to write one struct field at a time.
//!         Ok(Box::new(DemoBuilder {
//!             code: None,
//!             message: None,
//!             out: self.out,
//!         }))
//!     }
//! }
//!
//! struct DemoBuilder<'a> {
//!     code: Option<u32>,
//!     message: Option<String>,
//!     out: &'a mut Option<Demo>,
//! }
//!
//! impl<'a> Map for DemoBuilder<'a> {
//!     fn key(&mut self, k: &str) -> Result<Box<dyn Visitor + '_>> {
//!         // Figure out which field is being deserialized and return a
//!         // visitor to write it.
//!         //
//!         // The code here ignores unrecognized fields but an implementation
//!         // would be free to return an error instead. Similarly an
//!         // implementation may want to check for duplicate fields by
//!         // returning an error if the current field already has a value.
//!         match k {
//!             "code" => Ok(Box::new(Deserialize::begin(&mut self.code))),
//!             "message" => Ok(Box::new(Deserialize::begin(&mut self.message))),
//!             _ => Ok(<dyn Visitor>::ignore()),
//!         }
//!     }
//!
//!     fn finish(&mut self) -> Result<()> {
//!         // Make sure we have every field and then write the output object
//!         // into self.out.
//!         let code = self.code.take().ok_or(microserde::Error)?;
//!         let message = self.message.take().ok_or(microserde::Error)?;
//!         *self.out = Some(Demo { code, message });
//!         Ok(())
//!     }
//! }
//!
//! impl Deserialize for Demo {
//!     type Visitor<'a> = DemoVisitor<'a>;
//!
//!     fn begin(out: &mut Option<Self>) -> Self::Visitor<'_> {
//!         DemoVisitor { out }
//!     }
//! }
//! ```

mod impls;

use crate::error::{Error, Result};
use crate::lib::Box;

/// Trait for data structures that can be deserialized from a JSON string.
///
/// [Refer to the module documentation for examples.][crate::de]
pub trait Deserialize: Sized {
    /// A visitor holding a mutable reference to the output slot, into which
    /// the deserialized value is written.
    type Visitor<'a>: Visitor + 'a
    where
        Self: 'a;

    /// Build a visitor that writes into the given output slot.
    fn begin(out: &mut Option<Self>) -> Self::Visitor<'_>;

    // Not public API. This method is only intended for Option<T>, should not
    // need to be implemented outside of this crate.
    #[doc(hidden)]
    #[inline]
    fn default() -> Option<Self> {
        None
    }
}

/// A single scalar value.
pub enum Scalar<'a> {
    Null,
    Bool(bool),
    Str(&'a str),
    Negative(i64),
    Nonnegative(u64),
    Float(f64),
}

/// Trait that can write data into an output place.
///
/// [Refer to the module documentation for examples.][crate::de]
pub trait Visitor {
    /// Write a scalar value into the output slot.
    fn scalar(&mut self, s: &Scalar) -> Result<()> {
        let _ = s;
        Err(Error)
    }

    /// Begin a sequence (JSON array). Consumes the visitor and returns a
    /// builder owning everything the visitor held, so that the builder can
    /// hand out element visitors and finally write the output slot.
    fn seq<'s>(self: Box<Self>) -> Result<Box<dyn Seq + 's>>
    where
        Self: 's,
    {
        Err(Error)
    }

    /// Begin a map (JSON object). Consumes the visitor and returns a builder
    /// owning everything the visitor held, so that the builder can hand out
    /// value visitors and finally write the output slot.
    fn map<'s>(self: Box<Self>) -> Result<Box<dyn Map + 's>>
    where
        Self: 's,
    {
        Err(Error)
    }
}

/// Trait that can hand out visitors to write sequence elements.
///
/// [Refer to the module documentation for examples.][crate::de]
pub trait Seq {
    fn element(&mut self) -> Result<Box<dyn Visitor + '_>>;
    fn finish(&mut self) -> Result<()>;

    /// Write a scalar element. Equivalent to writing through the visitor
    /// returned by `element`, which is what the default implementation does;
    /// implementations can override this to write the element without
    /// allocating a boxed visitor.
    fn scalar(&mut self, s: &Scalar) -> Result<()> {
        self.element()?.scalar(s)
    }
}

/// Trait that can hand out visitors to write values of a map.
///
/// [Refer to the module documentation for examples.][crate::de]
pub trait Map {
    fn key(&mut self, k: &str) -> Result<Box<dyn Visitor + '_>>;
    fn finish(&mut self) -> Result<()>;

    /// Write a scalar value under the given key. Equivalent to writing
    /// through the visitor returned by `key`, which is what the default
    /// implementation does; implementations can override this to write the
    /// value without allocating a boxed visitor.
    fn scalar(&mut self, k: &str, s: &Scalar) -> Result<()> {
        self.key(k)?.scalar(s)
    }
}

/// A visitor that holds nothing but a mutable reference to the output slot.
///
/// This is the visitor type used by the `Deserialize` impls built into
/// microserde for types whose visitor needs no state besides the output slot.
///
/// Note that the orphan rules prevent other crates from writing `impl Visitor
/// for Place<'_, TheirType>`, so outside of microserde a bespoke visitor
/// struct holding the output slot must be defined instead. [Refer to the
/// module documentation for examples.][crate::de]
pub struct Place<'a, T> {
    /// The output slot. Upon successful deserialization the output object is
    /// written here as `Some(T)`.
    pub out: &'a mut Option<T>,
}

impl<'a, T> Place<'a, T> {
    pub fn new(out: &'a mut Option<T>) -> Self {
        Place { out }
    }
}

// Not public API. Implemented by types that deserialize by delegating to an
// inner type and wrapping the result: `#[serde(transparent)]` newtypes and
// `Box<T>`.
#[doc(hidden)]
pub trait Transparent: Sized {
    type Inner: Deserialize;
    fn wrap(inner: Self::Inner) -> Self;
}

// Not public API. The visitor type of `#[serde(transparent)]` derived impls.
#[doc(hidden)]
pub struct TransparentVisitor<'a, T: Transparent> {
    out: &'a mut Option<T>,
}

// Not public API. The `Deserialize::begin` of `#[serde(transparent)]` derived
// impls.
#[doc(hidden)]
pub fn transparent<T: Transparent>(out: &mut Option<T>) -> TransparentVisitor<'_, T> {
    TransparentVisitor { out }
}

impl<'a, T: Transparent> Visitor for TransparentVisitor<'a, T> {
    fn scalar(&mut self, s: &Scalar) -> Result<()> {
        let mut value: Option<T::Inner> = None;
        Deserialize::begin(&mut value).scalar(s)?;
        *self.out = Some(T::wrap(value.ok_or(Error)?));
        Ok(())
    }

    fn seq<'s>(self: Box<Self>) -> Result<Box<dyn Seq + 's>>
    where
        Self: 's,
    {
        let mut value = Box::new(None);
        let ptr = careful!(&mut *value as &mut Option<T::Inner>);
        Ok(Box::new(TransparentSeq {
            out: self.out,
            seq: Box::new(Deserialize::begin(ptr)).seq()?,
            value,
        }))
    }

    fn map<'s>(self: Box<Self>) -> Result<Box<dyn Map + 's>>
    where
        Self: 's,
    {
        let mut value = Box::new(None);
        let ptr = careful!(&mut *value as &mut Option<T::Inner>);
        Ok(Box::new(TransparentMap {
            out: self.out,
            map: Box::new(Deserialize::begin(ptr)).map()?,
            value,
        }))
    }
}

struct TransparentSeq<'a, T: Transparent + 'a> {
    out: &'a mut Option<T>,
    // Borrows from `value`, so it is declared first to be dropped first.
    seq: Box<dyn Seq + 'a>,
    value: Box<Option<T::Inner>>,
}

impl<'a, T: Transparent> Seq for TransparentSeq<'a, T> {
    fn element(&mut self) -> Result<Box<dyn Visitor + '_>> {
        self.seq.element()
    }

    fn finish(&mut self) -> Result<()> {
        self.seq.finish()?;
        *self.out = Some(T::wrap(self.value.take().ok_or(Error)?));
        Ok(())
    }

    fn scalar(&mut self, s: &Scalar) -> Result<()> {
        self.seq.scalar(s)
    }
}

struct TransparentMap<'a, T: Transparent + 'a> {
    out: &'a mut Option<T>,
    // Borrows from `value`, so it is declared first to be dropped first.
    map: Box<dyn Map + 'a>,
    value: Box<Option<T::Inner>>,
}

impl<'a, T: Transparent> Map for TransparentMap<'a, T> {
    fn key(&mut self, k: &str) -> Result<Box<dyn Visitor + '_>> {
        self.map.key(k)
    }

    fn finish(&mut self) -> Result<()> {
        self.map.finish()?;
        *self.out = Some(T::wrap(self.value.take().ok_or(Error)?));
        Ok(())
    }

    fn scalar(&mut self, k: &str, s: &Scalar) -> Result<()> {
        self.map.scalar(k, s)
    }
}