Skip to main content

deser_core/ser/
handle.rs

1//! References to values that are serialized with their type erased.
2use alloc::boxed::Box;
3use core::fmt;
4
5use crate::State;
6use crate::adapted::Adapted;
7use crate::error::Error;
8use crate::event::ContainerShape;
9use crate::ser::boxed::{self, Boxed};
10use crate::ser::{Begin, Describe, Emit, PlainSink, Serialize};
11
12/// A value that is serialized, with its type erased.
13///
14/// This is the trait object behind [`SerializeRef`] and
15/// [`SerializeHandle`], it's implemented for [`Adapted`].
16pub(crate) trait Erased: Sync {
17    fn erased_serialize(&self, state: &mut State) -> Result<Emit<'_>, Error>;
18    fn erased_finish(&self, state: &mut State) -> Result<(), Error>;
19    fn erased_is_optional(&self) -> bool;
20    fn erased_container_shape(&self) -> ContainerShape;
21    fn erased_describe(&self, d: &mut dyn Describe);
22    fn erased_begin(&self, state: &mut State) -> Result<Begin<'_>, Error>;
23    fn erased_is_plain_value(&self) -> bool;
24    fn erased_emit_plain(&self, sink: &mut dyn PlainSink) -> Result<(), Error>;
25    fn erased_plain_cost(&self, budget: usize) -> Option<usize>;
26}
27
28impl<A: Serialize<T>, T: ?Sized + Sync> Erased for Adapted<A, T> {
29    fn erased_serialize(&self, state: &mut State) -> Result<Emit<'_>, Error> {
30        A::serialize(self.get(), state)
31    }
32
33    fn erased_finish(&self, state: &mut State) -> Result<(), Error> {
34        A::finish(self.get(), state)
35    }
36
37    fn erased_is_optional(&self) -> bool {
38        A::is_optional(self.get())
39    }
40
41    fn erased_container_shape(&self) -> ContainerShape {
42        A::container_shape(self.get())
43    }
44
45    fn erased_describe(&self, d: &mut dyn Describe) {
46        A::describe(self.get(), d)
47    }
48
49    fn erased_begin(&self, state: &mut State) -> Result<Begin<'_>, Error> {
50        A::__private_begin(self.get(), state)
51    }
52
53    fn erased_is_plain_value(&self) -> bool {
54        A::__private_is_plain_value(self.get())
55    }
56
57    fn erased_emit_plain(&self, sink: &mut dyn PlainSink) -> Result<(), Error> {
58        A::__private_emit_plain(self.get(), sink)
59    }
60
61    fn erased_plain_cost(&self, budget: usize) -> Option<usize> {
62        A::__private_plain_cost(self.get(), budget)
63    }
64}
65
66/// A reference to a value that is serialized.
67///
68/// This is the type erased form of a [`Serialize`] value (and an adapter
69/// if it's serialized with one).  The serializers of the data formats
70/// receive the values as references, for instance from the
71/// [`SerializeDriver`](crate::ser::SerializeDriver).  The methods of the
72/// reference invoke the ones of [`Serialize`].
73///
74/// ```
75/// use deser::adapters::DisplayFromStr;
76/// use deser::ser::SerializeRef;
77///
78/// let value = 42u32;
79/// assert!(!SerializeRef::new(&value).is_optional());
80///
81/// // serializes as string
82/// let value = SerializeRef::serialize_as::<DisplayFromStr, _>(&value);
83/// ```
84///
85/// Deserialization has no equivalent: values are type erased by creating
86/// their [`Sink`](crate::de::Sink) (see
87/// [`Deserialize::deserialize_into`](crate::de::Deserialize::deserialize_into)),
88/// which is already in the middle of deserializing them.
89#[derive(Clone, Copy)]
90pub struct SerializeRef<'a> {
91    value: &'a (dyn Erased + 'a),
92}
93
94impl<'a> SerializeRef<'a> {
95    /// Creates a reference to a value.
96    #[inline(always)]
97    pub fn new<T: Serialize>(value: &'a T) -> SerializeRef<'a> {
98        SerializeRef {
99            value: Adapted::<T, T>::new(value),
100        }
101    }
102
103    /// Creates a reference to a value that is serialized with an adapter.
104    ///
105    /// See [`adapters`](crate::adapters).
106    #[inline(always)]
107    pub fn serialize_as<A: Serialize<T>, T: Sync>(value: &'a T) -> SerializeRef<'a> {
108        SerializeRef {
109            value: Adapted::<A, T>::erased(value),
110        }
111    }
112
113    /// Creates a reference from a trait object.
114    #[inline(always)]
115    pub(crate) fn from_dyn(value: &'a (dyn Erased + 'a)) -> SerializeRef<'a> {
116        SerializeRef { value }
117    }
118
119    /// Returns the trait object.
120    #[inline(always)]
121    pub(crate) fn as_dyn(self) -> &'a (dyn Erased + 'a) {
122        self.value
123    }
124
125    /// Serializes the value (see [`Serialize::serialize`]).
126    #[inline]
127    pub fn serialize(self, state: &mut State) -> Result<Emit<'a>, Error> {
128        self.value.erased_serialize(state)
129    }
130
131    /// Invoked after the serialization finished (see [`Serialize::finish`]).
132    #[inline]
133    pub fn finish(self, state: &mut State) -> Result<(), Error> {
134        self.value.erased_finish(state)
135    }
136
137    /// Checks if the value is optional (see [`Serialize::is_optional`]).
138    #[inline]
139    pub fn is_optional(self) -> bool {
140        self.value.erased_is_optional()
141    }
142
143    /// Returns the shape of the value (see [`Serialize::container_shape`]).
144    #[inline]
145    pub fn container_shape(self) -> ContainerShape {
146        self.value.erased_container_shape()
147    }
148
149    /// Describes the Rust shape of the value (see [`Serialize::describe`]).
150    pub fn describe(self, d: &mut dyn Describe) {
151        self.value.erased_describe(d)
152    }
153
154    /// Begins the serialization (see `Serialize::__private_begin`).
155    #[inline]
156    pub(crate) fn begin(self, state: &mut State) -> Result<Begin<'a>, Error> {
157        self.value.erased_begin(state)
158    }
159
160    /// Returns `true` if the value is plain (see
161    /// `Serialize::__private_is_plain_value`).
162    #[inline]
163    pub(crate) fn is_plain_value(self) -> bool {
164        self.value.erased_is_plain_value()
165    }
166
167    /// Emits the events of a plain value (see
168    /// `Serialize::__private_emit_plain`).
169    #[inline]
170    pub(crate) fn emit_plain(self, sink: &mut dyn PlainSink) -> Result<(), Error> {
171        self.value.erased_emit_plain(sink)
172    }
173
174    /// Returns the budget that is left after emitting the plain value (see
175    /// `Serialize::__private_plain_cost`).
176    #[inline]
177    pub(crate) fn plain_cost(self, budget: usize) -> Option<usize> {
178        self.value.erased_plain_cost(budget)
179    }
180}
181
182impl fmt::Debug for SerializeRef<'_> {
183    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
184        f.debug_struct("SerializeRef").finish_non_exhaustive()
185    }
186}
187
188impl<'a, T: Serialize> From<&'a T> for SerializeRef<'a> {
189    #[inline(always)]
190    fn from(value: &'a T) -> SerializeRef<'a> {
191        SerializeRef::new(value)
192    }
193}
194
195impl Serialize for SerializeRef<'_> {
196    #[inline]
197    fn serialize<'b>(value: &'b Self, state: &mut State) -> Result<Emit<'b>, Error> {
198        value.serialize(state)
199    }
200
201    #[inline]
202    fn finish(value: &Self, state: &mut State) -> Result<(), Error> {
203        (*value).finish(state)
204    }
205
206    #[inline]
207    fn is_optional(value: &Self) -> bool {
208        (*value).is_optional()
209    }
210
211    #[inline]
212    fn container_shape(value: &Self) -> ContainerShape {
213        (*value).container_shape()
214    }
215
216    fn describe(value: &Self, d: &mut dyn Describe) {
217        (*value).describe(d)
218    }
219
220    #[inline]
221    fn __private_begin<'b>(value: &'b Self, state: &mut State) -> Result<Begin<'b>, Error> {
222        value.begin(state)
223    }
224
225    #[inline]
226    fn __private_is_plain_value(value: &Self) -> bool {
227        value.is_plain_value()
228    }
229
230    #[inline]
231    fn __private_emit_plain(value: &Self, sink: &mut dyn PlainSink) -> Result<(), Error> {
232        value.emit_plain(sink)
233    }
234
235    #[inline]
236    fn __private_plain_cost(value: &Self, budget: usize) -> Option<usize> {
237        value.plain_cost(budget)
238    }
239}
240
241/// A handle to a value that is serialized.
242///
243/// During serialization it's common to be in a situation where one needs
244/// to return a locally constructed [`Serialize`].  This is where
245/// [`SerializeHandle`] comes in.  The handle either borrows the value (see
246/// [`to`](Self::to) and [`SerializeRef`]) or owns it (see
247/// [`arena`](Self::arena) and [`heap`](Self::heap)).
248///
249/// Unlike the [`SinkHandle`](crate::de::SinkHandle) of deserialization,
250/// which holds a sink that is already deserializing a value, this holds a
251/// value that is not serialized yet.  The serialization equivalent of a
252/// sink is an emitter in a [`Emit`].  The constructors line up:
253/// [`to`](Self::to) borrows, [`arena`](Self::arena) and
254/// [`heap`](Self::heap) own in the same way for both handles.
255pub struct SerializeHandle<'a>(pub(crate) HandleInner<'a>);
256
257pub(crate) enum HandleInner<'a> {
258    Borrowed(SerializeRef<'a>),
259    // owned values are `Send` so that the serialization can move between
260    // threads
261    Owned(Boxed<dyn Erased + Send + 'a>),
262}
263
264impl<'a> SerializeHandle<'a> {
265    /// Creates a borrowed handle to a value.
266    #[inline(always)]
267    pub fn to<S: Serialize>(value: &'a S) -> SerializeHandle<'a> {
268        SerializeHandle(HandleInner::Borrowed(SerializeRef::new(value)))
269    }
270
271    /// Creates an owned handle to a value in the arena of the state.
272    ///
273    /// This is how owned values are typically created (for instance for
274    /// [`Emit::Forward`]), see [`Boxed`].
275    #[inline(always)]
276    pub fn arena<S: Serialize + Send + 'a>(value: S, state: &mut State) -> SerializeHandle<'a> {
277        SerializeHandle(HandleInner::Owned(boxed::unsize(
278            Boxed::arena(Adapted::<S, S>::owned(value), state),
279            |x| x as *mut (dyn Erased + Send + 'a),
280        )))
281    }
282
283    /// Creates an owned handle to a value on the heap.
284    ///
285    /// Unlike [`arena`](Self::arena) the value does not need a state and is
286    /// independent of any serialization.
287    pub fn heap<S: Serialize + Send + 'a>(value: S) -> SerializeHandle<'a> {
288        SerializeHandle(HandleInner::Owned(Boxed::from(
289            Box::new(Adapted::<S, S>::owned(value)) as Box<dyn Erased + Send + 'a>,
290        )))
291    }
292
293    /// Returns a reference to the value.
294    #[inline(always)]
295    pub fn get(&self) -> SerializeRef<'_> {
296        match self.0 {
297            HandleInner::Borrowed(value) => value,
298            HandleInner::Owned(ref value) => SerializeRef::from_dyn(&**value),
299        }
300    }
301}
302
303impl<'a> From<SerializeRef<'a>> for SerializeHandle<'a> {
304    #[inline(always)]
305    fn from(value: SerializeRef<'a>) -> SerializeHandle<'a> {
306        SerializeHandle(HandleInner::Borrowed(value))
307    }
308}
309
310impl fmt::Debug for SerializeHandle<'_> {
311    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
312        f.debug_struct("SerializeHandle").finish_non_exhaustive()
313    }
314}
315
316impl Serialize for SerializeHandle<'_> {
317    #[inline]
318    fn serialize<'b>(value: &'b Self, state: &mut State) -> Result<Emit<'b>, Error> {
319        value.get().serialize(state)
320    }
321
322    #[inline]
323    fn finish(value: &Self, state: &mut State) -> Result<(), Error> {
324        value.get().finish(state)
325    }
326
327    #[inline]
328    fn is_optional(value: &Self) -> bool {
329        value.get().is_optional()
330    }
331
332    #[inline]
333    fn container_shape(value: &Self) -> ContainerShape {
334        value.get().container_shape()
335    }
336
337    fn describe(value: &Self, d: &mut dyn Describe) {
338        value.get().describe(d)
339    }
340
341    #[inline]
342    fn __private_begin<'b>(value: &'b Self, state: &mut State) -> Result<Begin<'b>, Error> {
343        value.get().begin(state)
344    }
345
346    #[inline]
347    fn __private_is_plain_value(value: &Self) -> bool {
348        value.get().is_plain_value()
349    }
350
351    #[inline]
352    fn __private_emit_plain(value: &Self, sink: &mut dyn PlainSink) -> Result<(), Error> {
353        value.get().emit_plain(sink)
354    }
355
356    #[inline]
357    fn __private_plain_cost(value: &Self, budget: usize) -> Option<usize> {
358        value.get().plain_cost(budget)
359    }
360}