Skip to main content

deser_core/ser/
emit.rs

1use crate::event::{Atom, Bytes};
2use crate::ser::boxed::unsize;
3use crate::ser::{Boxed, MapEmitter, SeqEmitter, SerializeHandle, StructEmitter};
4use crate::{State, Text};
5use alloc::string::String;
6
7/// Describes how a value is emitted, returned by
8/// [`Serialize::serialize`](crate::ser::Serialize::serialize).
9///
10/// A value is either emitted as an atom, by a stateful emitter or by
11/// forwarding to another value.  For instance `Emit::Atom(Atom::Bool(true))`
12/// is emitted to a serializer directly.  On the other hand an `Emit::Map`
13/// contains a stateful emitter that keeps yielding values until it's done
14/// walking over the map.
15///
16/// The emitters are typically allocated in the arena of the state
17/// with [`Emit::seq`], [`Emit::map`] and [`Emit::structure`] (see
18/// [`Boxed`]).  They are the serialization equivalent of the
19/// [`Sink`](crate::de::Sink)s of deserialization: they hold the state of a
20/// value that is being serialized.
21pub enum Emit<'a> {
22    Atom(Atom<'a>),
23    Struct(Boxed<dyn StructEmitter + 'a>),
24    Map(Boxed<dyn MapEmitter + 'a>),
25    Seq(Boxed<dyn SeqEmitter + 'a>),
26    /// Serializes another value in place of this one.
27    ///
28    /// The driver serializes the value in the handle as if it was produced
29    /// instead of the value that returned the `Emit`.  This is useful to
30    /// serialize a value by converting it into another value first as the
31    /// handle can own that value:
32    ///
33    /// ```
34    /// use deser::ser::{Emit, Serialize, SerializeHandle};
35    /// use deser::{Error, State};
36    ///
37    /// struct Point(u32, u32);
38    ///
39    /// impl Serialize for Point {
40    ///     fn serialize<'a>(value: &'a Self, state: &mut State) -> Result<Emit<'a>, Error> {
41    ///         // serialize as a vector
42    ///         Ok(Emit::Forward(SerializeHandle::arena(
43    ///             vec![value.0, value.1],
44    ///             state,
45    ///         )))
46    ///     }
47    /// }
48    /// ```
49    ///
50    /// The [`container_shape`](crate::ser::Serialize::container_shape) of the
51    /// value that returned the `Emit` is not used, the forwarded value provides
52    /// its own.
53    /// [`finish`](crate::ser::Serialize::finish) is invoked on the forwarded
54    /// value first and then on the value that returned the `Emit`.
55    ///
56    /// Values that forward cannot be flattened into structs.
57    Forward(SerializeHandle<'a>),
58}
59
60impl<'a> Emit<'a> {
61    /// Emits a sequence with an emitter in the arena of the
62    /// serialization.
63    #[inline(always)]
64    pub fn seq<E: SeqEmitter + 'a>(emitter: E, state: &mut State) -> Emit<'a> {
65        Emit::Seq(unsize(Boxed::arena(emitter, state), |x| {
66            x as *mut (dyn SeqEmitter + 'a)
67        }))
68    }
69
70    /// Emits a map with an emitter in the arena of the state.
71    #[inline(always)]
72    pub fn map<E: MapEmitter + 'a>(emitter: E, state: &mut State) -> Emit<'a> {
73        Emit::Map(unsize(Boxed::arena(emitter, state), |x| {
74            x as *mut (dyn MapEmitter + 'a)
75        }))
76    }
77
78    /// Emits a struct with an emitter in the arena of the
79    /// serialization.
80    #[inline(always)]
81    pub fn structure<E: StructEmitter + 'a>(emitter: E, state: &mut State) -> Emit<'a> {
82        Emit::Struct(unsize(Boxed::arena(emitter, state), |x| {
83            x as *mut (dyn StructEmitter + 'a)
84        }))
85    }
86}
87
88impl<'a> From<Atom<'a>> for Emit<'a> {
89    fn from(atom: Atom<'a>) -> Self {
90        Emit::Atom(atom)
91    }
92}
93
94macro_rules! impl_from {
95    ($ty:ty, $atom:ident) => {
96        impl From<$ty> for Emit<'static> {
97            fn from(value: $ty) -> Self {
98                Emit::Atom(Atom::$atom(value as _))
99            }
100        }
101    };
102}
103
104impl_from!(u64, U64);
105impl_from!(i64, I64);
106impl_from!(usize, U64);
107impl_from!(isize, I64);
108impl_from!(bool, Bool);
109impl_from!(char, Char);
110
111impl From<f64> for Emit<'static> {
112    fn from(value: f64) -> Self {
113        Emit::Atom(Atom::F64(value))
114    }
115}
116
117impl From<f32> for Emit<'static> {
118    fn from(value: f32) -> Self {
119        Emit::Atom(Atom::F32(value))
120    }
121}
122
123impl From<()> for Emit<'static> {
124    fn from(_: ()) -> Emit<'static> {
125        Emit::Atom(Atom::Null)
126    }
127}
128
129impl<'a> From<&'a str> for Emit<'a> {
130    fn from(value: &'a str) -> Emit<'a> {
131        Emit::Atom(Atom::Str(Text::borrowed(value)))
132    }
133}
134
135impl<'a> From<&'a [u8]> for Emit<'a> {
136    fn from(value: &'a [u8]) -> Emit<'a> {
137        Emit::Atom(Atom::Bytes(Bytes::borrowed(value)))
138    }
139}
140
141impl From<String> for Emit<'static> {
142    fn from(value: String) -> Emit<'static> {
143        Emit::Atom(Atom::Str(Text::owned(value)))
144    }
145}
146
147#[cfg(target_pointer_width = "64")]
148const _: () = assert!(core::mem::size_of::<Emit<'static>>() == 32);
149#[cfg(target_pointer_width = "32")]
150const _: () = assert!(core::mem::size_of::<Emit<'static>>() == 24);