deser/ser/
mod.rs

1//! Generic data structure serialization framework.
2//!
3//! Serialization in deser is based on the [`Serialize`] trait which produces
4//! [`Chunk`] objects.  A serializable object walks an object and produces either
5//! an atomic chunk or a chunk containing an emitter which yields further values.
6//!
7//! This allows the system to support unlimited recursion.  This is tricky to with
8//! the borrow checker due to lifetimes.  The [`SerializeDriver`] is provided
9//! which yields events from the produced chunks as a safe convenience API.
10//!
11//! # Serializing primitives
12//!
13//! Primitives are trivial to serialize as you just directly return the right type
14//! of [`Chunk`] from the serialization method.  In this example we also provide
15//! an optional [`Descriptor`] which can help serializers make better decisions.
16//!
17//! ```rust
18//! use deser::ser::{Serialize, SerializerState, Chunk};
19//! use deser::{Atom, Descriptor, Error};
20//!
21//! struct MyInt(u32);
22//!
23//! #[derive(Debug)]
24//! struct MyIntDescriptor;
25//!
26//! impl Descriptor for MyIntDescriptor {
27//!     fn name(&self) -> Option<&str> {
28//!         Some("MyInt")
29//!     }
30//!
31//!     fn precision(&self) -> Option<usize> {
32//!         Some(32)
33//!     }
34//! }
35//!
36//! impl Serialize for MyInt {
37//!     fn descriptor(&self) -> &dyn Descriptor {
38//!         &MyIntDescriptor
39//!     }
40//!
41//!     fn serialize(&self, state: &SerializerState) -> Result<Chunk, Error> {
42//!         // one can also just do `self.0.serialize(state)`
43//!         Ok(Chunk::Atom(Atom::U64(self.0 as u64)))
44//!     }
45//! }
46//! ```
47//!
48//! # Serializing structs
49//!
50//! To serialize compounds like structs you return a chunk containing an emitter.
51//! Note that the emitter returns a [`SerializeHandle`].  If want you want to
52//! serialize is not already available the handle can hold a boxed [`Serialize`].
53//!
54//! ```rust
55//! use std::borrow::Cow;
56//! use deser::ser::{Serialize, SerializerState, Chunk, StructEmitter, SerializeHandle};
57//! use deser::Error;
58//!
59//! struct User {
60//!     id: u32,
61//!     username: String,
62//! }
63//!
64//! impl Serialize for User {
65//!     fn serialize(&self, _state: &SerializerState) -> Result<Chunk, Error> {
66//!         Ok(Chunk::Struct(Box::new(UserEmitter {
67//!             user: self,
68//!             index: 0,
69//!         })))
70//!     }
71//! }
72//!
73//! struct UserEmitter<'a> {
74//!     user: &'a User,
75//!     index: usize,
76//! }
77//!
78//! impl<'a> StructEmitter for UserEmitter<'a> {
79//!     fn next(&mut self, _state: &SerializerState)
80//!         -> Result<Option<(Cow<'_, str>, SerializeHandle)>, Error>
81//!     {
82//!         let index = self.index;
83//!         self.index += 1;
84//!         Ok(match index {
85//!             0 => Some(("id".into(), SerializeHandle::to(&self.user.id))),
86//!             1 => Some(("username".into(), SerializeHandle::to(&self.user.username))),
87//!             _ => None
88//!         })
89//!     }
90//! }
91//! ```
92use std::borrow::Cow;
93use std::cell::{Ref, RefMut};
94use std::fmt;
95use std::ops::Deref;
96
97use crate::descriptors::{Descriptor, NullDescriptor};
98use crate::error::Error;
99use crate::extensions::Extensions;
100
101mod chunk;
102mod driver;
103mod impls;
104
105pub use self::chunk::Chunk;
106
107pub use driver::SerializeDriver;
108
109/// A handle to a [`Serialize`] type.
110///
111/// During serialization it common to be in a situation where one needs to
112/// return locally constructed [`Serialize`].  This is where
113/// [`SerializeHandle`] comes in.  In cases where the [`Serialize`] cannot
114/// be borrowed it can be boxed up inside the handle.
115///
116/// The equivalent for deserialization is the
117/// [`SinkHandle`](crate::de::SinkHandle).
118pub enum SerializeHandle<'a> {
119    /// A borrowed reference to a [`Serialize`].
120    Borrowed(&'a dyn Serialize),
121    /// A boxed up [`Serialize`].
122    Owned(Box<dyn Serialize + 'a>),
123}
124
125impl<'a> Deref for SerializeHandle<'a> {
126    type Target = dyn Serialize + 'a;
127
128    fn deref(&self) -> &Self::Target {
129        match self {
130            SerializeHandle::Borrowed(val) => *val,
131            SerializeHandle::Owned(val) => &**val,
132        }
133    }
134}
135
136impl<'a> SerializeHandle<'a> {
137    /// Create a borrowed handle to a [`Serialize`].
138    pub fn to<S: Serialize + 'a>(val: &'a S) -> SerializeHandle<'a> {
139        SerializeHandle::Borrowed(val as &dyn Serialize)
140    }
141
142    /// Create an owned handle to a heap allocated [`Serialize`].
143    pub fn boxed<S: Serialize + 'a>(val: S) -> SerializeHandle<'a> {
144        SerializeHandle::Owned(Box::new(val))
145    }
146}
147
148/// The current state of the serializer.
149///
150/// During serializer the [`SerializerState`] acts as a communciation device between
151/// the serializable types as the serializer.
152pub struct SerializerState<'a> {
153    extensions: Extensions,
154    descriptor_stack: Vec<&'a dyn Descriptor>,
155}
156
157impl<'a> fmt::Debug for SerializerState<'a> {
158    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
159        struct Stack<'a>(&'a [&'a dyn Descriptor]);
160        struct Entry<'a>(&'a dyn Descriptor);
161
162        impl<'a> fmt::Debug for Entry<'a> {
163            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
164                f.debug_struct("Layer")
165                    .field("type_name", &self.0.name())
166                    .field("precision", &self.0.precision())
167                    .field("unordered", &self.0.unordered())
168                    .finish()
169            }
170        }
171
172        impl<'a> fmt::Debug for Stack<'a> {
173            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
174                let mut l = f.debug_list();
175                for item in self.0.iter() {
176                    l.entry(&Entry(*item));
177                }
178                l.finish()
179            }
180        }
181
182        f.debug_struct("SerializerState")
183            .field("extensions", &self.extensions)
184            .field("stack", &Stack(&self.descriptor_stack))
185            .finish()
186    }
187}
188
189impl<'a> SerializerState<'a> {
190    /// Returns an extension value.
191    pub fn get<T: Default + fmt::Debug + 'static>(&self) -> Ref<'_, T> {
192        self.extensions.get()
193    }
194
195    /// Returns a mutable extension value.
196    pub fn get_mut<T: Default + fmt::Debug + 'static>(&self) -> RefMut<'_, T> {
197        self.extensions.get_mut()
198    }
199
200    /// Returns the current recursion depth.
201    pub fn depth(&self) -> usize {
202        self.descriptor_stack.len()
203    }
204
205    /// Returns the topmost descriptor.
206    ///
207    /// This descriptor always points to a container as the descriptor of a value itself
208    /// will always be passed to the callback explicitly.
209    pub fn top_descriptor(&self) -> Option<&dyn Descriptor> {
210        self.descriptor_stack.last().copied()
211    }
212}
213
214/// A struct emitter.
215///
216/// A struct emitter is a simplified version of a [`MapEmitter`] which produces struct
217/// field and value in one go.  The object model itself however does not know structs,
218/// it only knows about maps.
219pub trait StructEmitter {
220    /// Produces the next field and value in the struct.
221    fn next(
222        &mut self,
223        state: &SerializerState,
224    ) -> Result<Option<(Cow<'_, str>, SerializeHandle)>, Error>;
225}
226
227/// A map emitter.
228pub trait MapEmitter {
229    /// Produces the next key in the map.
230    ///
231    /// If this reached the end of the map `None` shall be returned.  The expectation
232    /// is that this method changes an internal state in the emitter and the next
233    /// call to [`next_value`](Self::next_value) returns the corresponding value.
234    fn next_key(&mut self, state: &SerializerState) -> Result<Option<SerializeHandle>, Error>;
235
236    /// Produces the next value in the map.
237    ///
238    /// # Panics
239    ///
240    /// This method shall panic if the emitter is not able to produce a value because
241    /// the emitter is in the wrong state.
242    fn next_value(&mut self, state: &SerializerState) -> Result<SerializeHandle, Error>;
243}
244
245/// A sequence emitter.
246pub trait SeqEmitter {
247    /// Produces the next item in the sequence.
248    fn next(&mut self, state: &SerializerState) -> Result<Option<SerializeHandle>, Error>;
249}
250
251/// A data structure that can be serialized into any data format supported by Deser.
252///
253/// This trait provides two things:
254///
255/// * [`descriptor`](Self::descriptor) returns a reference to the closest descriptor
256///   of this value.  The descriptor provides auxiliary information about the value
257///   that the serialization system does not expose.
258/// * [`serialize`](Self::serialize) serializes the value into a [`Chunk`].  For
259///   compound values like lists or similar, the piece contains a boxed emitter
260///   which can be further processed to walk the embedded compound value.
261pub trait Serialize {
262    /// Serializes this serializable.
263    fn serialize(&self, state: &SerializerState) -> Result<Chunk, Error>;
264
265    /// Invoked after the serialization finished.
266    ///
267    /// This is primarily useful to undo some state change in the serializer
268    /// state at the end of the processing.
269    fn finish(&self, _state: &SerializerState) -> Result<(), Error> {
270        Ok(())
271    }
272
273    /// Checks if the current value that would be serialized represents an
274    /// optional value.
275    ///
276    /// This can be used by an emitter to skip over values that are currently
277    /// in the optional state.  For instance `Option<T>` returns `true` here if
278    /// the value is `None` and the struct emitter created by the `derive` feature
279    /// will skip over these if `#[deser(skip_serializing_optionals)]` is set on
280    /// the struct.
281    fn is_optional(&self) -> bool {
282        false
283    }
284
285    /// Returns the descriptor of this serializable if it exists.
286    fn descriptor(&self) -> &dyn Descriptor {
287        &NullDescriptor
288    }
289
290    /// Hidden internal trait method to allow specializations of bytes.
291    ///
292    /// This method is used by `u8` and `Vec<T>` / `&[T]` to achieve special
293    /// casing of bytes for the serialization system.  It allows a vector of
294    /// bytes to be emitted as `Chunk::Bytes` rather than a `Seq`.
295    #[doc(hidden)]
296    fn __private_slice_as_bytes(_val: &[Self]) -> Option<Cow<'_, [u8]>>
297    where
298        Self: Sized,
299    {
300        None
301    }
302}
303
304#[test]
305fn test_serialize() {
306    let mut v = Vec::new();
307    let mut m = std::collections::BTreeMap::new();
308    m.insert(true, vec![vec![&b"x"[..], b"yyy"], vec![b"zzzz"]]);
309    m.insert(false, vec![]);
310
311    let mut driver = SerializeDriver::new(&m);
312    while let Some((event, _, _)) = driver.next().unwrap() {
313        v.push(format!("{:?}", event));
314    }
315
316    assert_eq!(
317        &v[..],
318        [
319            "MapStart",
320            "Atom(Bool(false))",
321            "SeqStart",
322            "SeqEnd",
323            "Atom(Bool(true))",
324            "SeqStart",
325            "SeqStart",
326            "Atom(Bytes([120]))",
327            "Atom(Bytes([121, 121, 121]))",
328            "SeqEnd",
329            "SeqStart",
330            "Atom(Bytes([122, 122, 122, 122]))",
331            "SeqEnd",
332            "SeqEnd",
333            "MapEnd",
334        ]
335    );
336}