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}