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    /// Like [`seq`](Self::seq) but the emitter does not need to outlive
88    /// `'a`.
89    ///
90    /// This is for the emitters of sequences which are generic over
91    /// adapters (see [`erase_unbounded`](crate::ser::handle::erase_unbounded)).
92    ///
93    /// # Safety
94    ///
95    /// The parts of `E` that do not outlive `'a` must be adapters that are
96    /// only used for their functions, `E` holds no values of them.
97    #[inline(always)]
98    pub(crate) unsafe fn seq_unbounded<E: SeqEmitter>(emitter: E, state: &mut State) -> Emit<'a> {
99        // like every type parameter, `E` outlives this function
100        let emitter = unsize(Boxed::arena(emitter, state), |x| {
101            x as *mut (dyn SeqEmitter + '_)
102        });
103        // SAFETY: guaranteed by the caller
104        Emit::Seq(unsafe {
105            core::mem::transmute::<Boxed<dyn SeqEmitter + '_>, Boxed<dyn SeqEmitter + 'a>>(emitter)
106        })
107    }
108
109    /// Like [`map`](Self::map) but the emitter does not need to outlive
110    /// `'a`.
111    ///
112    /// # Safety
113    ///
114    /// See [`seq_unbounded`](Self::seq_unbounded).
115    #[inline(always)]
116    pub(crate) unsafe fn map_unbounded<E: MapEmitter>(emitter: E, state: &mut State) -> Emit<'a> {
117        // like every type parameter, `E` outlives this function
118        let emitter = unsize(Boxed::arena(emitter, state), |x| {
119            x as *mut (dyn MapEmitter + '_)
120        });
121        // SAFETY: guaranteed by the caller
122        Emit::Map(unsafe {
123            core::mem::transmute::<Boxed<dyn MapEmitter + '_>, Boxed<dyn MapEmitter + 'a>>(emitter)
124        })
125    }
126}
127
128impl<'a> From<Atom<'a>> for Emit<'a> {
129    fn from(atom: Atom<'a>) -> Self {
130        Emit::Atom(atom)
131    }
132}
133
134macro_rules! impl_from {
135    ($ty:ty, $atom:ident) => {
136        impl From<$ty> for Emit<'static> {
137            fn from(value: $ty) -> Self {
138                Emit::Atom(Atom::$atom(value as _))
139            }
140        }
141    };
142}
143
144impl_from!(u64, U64);
145impl_from!(i64, I64);
146impl_from!(usize, U64);
147impl_from!(isize, I64);
148impl_from!(bool, Bool);
149impl_from!(char, Char);
150
151impl From<f64> for Emit<'static> {
152    fn from(value: f64) -> Self {
153        Emit::Atom(Atom::F64(value))
154    }
155}
156
157impl From<f32> for Emit<'static> {
158    fn from(value: f32) -> Self {
159        Emit::Atom(Atom::F32(value))
160    }
161}
162
163impl From<()> for Emit<'static> {
164    fn from(_: ()) -> Emit<'static> {
165        Emit::Atom(Atom::Null)
166    }
167}
168
169impl<'a> From<&'a str> for Emit<'a> {
170    fn from(value: &'a str) -> Emit<'a> {
171        Emit::Atom(Atom::Str(Text::borrowed(value)))
172    }
173}
174
175impl<'a> From<&'a [u8]> for Emit<'a> {
176    fn from(value: &'a [u8]) -> Emit<'a> {
177        Emit::Atom(Atom::Bytes(Bytes::borrowed(value)))
178    }
179}
180
181impl From<String> for Emit<'static> {
182    fn from(value: String) -> Emit<'static> {
183        Emit::Atom(Atom::Str(Text::owned(value)))
184    }
185}
186
187#[cfg(target_pointer_width = "64")]
188const _: () = assert!(core::mem::size_of::<Emit<'static>>() == 32);
189#[cfg(target_pointer_width = "32")]
190const _: () = assert!(core::mem::size_of::<Emit<'static>>() == 24);