Skip to main content

deser_core/de/
owned.rs

1use alloc::boxed::Box;
2use core::mem::ManuallyDrop;
3use core::ops::{Deref, DerefMut};
4use core::ptr::NonNull;
5
6use crate::State;
7use crate::adapters::DeserializeAs;
8use crate::de::arena::ArenaBox;
9use crate::de::{Deserialize, DeserializeDriver, Sink, SinkHandle};
10use crate::error::{Error, ErrorKind};
11
12struct NonuniqueBox<T: ?Sized> {
13    ptr: NonNull<T>,
14}
15
16// SAFETY: the box owns its value like a `Box<T>`.
17unsafe impl<T: ?Sized + Send> Send for NonuniqueBox<T> {}
18
19impl<T> NonuniqueBox<T> {
20    pub(crate) fn new(value: T) -> Self {
21        NonuniqueBox::from(Box::new(value))
22    }
23}
24
25impl<T: ?Sized> From<Box<T>> for NonuniqueBox<T> {
26    fn from(boxed: Box<T>) -> Self {
27        let ptr = Box::into_raw(boxed);
28        let ptr = unsafe { NonNull::new_unchecked(ptr) };
29        NonuniqueBox { ptr }
30    }
31}
32
33impl<T: ?Sized> Deref for NonuniqueBox<T> {
34    type Target = T;
35    fn deref(&self) -> &Self::Target {
36        unsafe { self.ptr.as_ref() }
37    }
38}
39
40impl<T: ?Sized> DerefMut for NonuniqueBox<T> {
41    fn deref_mut(&mut self) -> &mut Self::Target {
42        unsafe { self.ptr.as_mut() }
43    }
44}
45
46impl<T: ?Sized> Drop for NonuniqueBox<T> {
47    fn drop(&mut self) {
48        let ptr = self.ptr.as_ptr();
49        let _ = unsafe { Box::from_raw(ptr) };
50    }
51}
52
53/// Creates a reference with an unbounded lifetime.
54unsafe fn unbounded<'x, X>(ptr: *mut X) -> &'x mut X {
55    unsafe { &mut *ptr }
56}
57
58/// Utility to bundle a sink with a slot.
59///
60/// There are situations where one wants to be able to deserialize into
61/// a slot that needs to be allocated on the heap and hold it together
62/// with the sink handle.  Rust's lifetimes make this impossible so this
63/// abstraction is provided to allow this.
64///
65/// # Example
66///
67/// This example demonstrates the use of an [`OwnedSink`] to implement
68/// [`Deserialize`] for a newtype wrapper.  For simplicities sake only
69/// atoms have been implemented here.
70///
71/// ```rust
72/// use deser::{Atom, Error};
73/// use deser::de::{OwnedSink, SinkHandle, Sink, Deserialize};
74/// use deser::State;
75///
76/// struct AtomWrapper<T>(T);
77///
78/// impl<'de, T: Deserialize<'de>> Deserialize<'de> for AtomWrapper<T> {
79///     fn deserialize_into<'out>(
80///         out: &'out mut Option<Self>,
81///         state: &mut State,
82///     ) -> SinkHandle<'out, 'de> {
83///         SinkHandle::arena(
84///             WrapperSink { out, sink: OwnedSink::deserialize(state) },
85///             state,
86///         )
87///     }
88/// }
89///
90/// struct WrapperSink<'a, 'de, T> {
91///     out: &'a mut Option<AtomWrapper<T>>,
92///     sink: OwnedSink<'de, T>,
93/// }
94///
95/// impl<'a, 'de, T: Deserialize<'de>> Sink<'de> for WrapperSink<'a, 'de, T> {
96///     fn atom(
97///         &mut self,
98///         atom: Atom,
99///         state: &mut State,
100///     ) -> Result<(), Error> {
101///         self.sink.borrow_mut().atom(atom, state)
102///     }
103///     fn finish(&mut self, state: &mut State) -> Result<(), Error> {
104///         self.sink.borrow_mut().finish(state)?;
105///         *self.out = self.sink.take().map(AtomWrapper);
106///         Ok(())
107///     }
108/// }
109/// ```
110pub struct OwnedSink<'de, T> {
111    // The sink borrows from the storage (in the arena, like the sink).  The
112    // sink is always dropped before the storage is accessed (in `take`) or
113    // dropped.  The lifetime of the
114    // borrow is erased (to `'de` as the handle cannot outlive that).
115    storage: ArenaBox<Option<T>>,
116    sink: ManuallyDrop<SinkHandle<'de, 'de>>,
117}
118
119impl<'de, T: Deserialize<'de>> OwnedSink<'de, T> {
120    /// Creates a new owned sink for a given type.
121    ///
122    /// This begins the deserialization with [`Deserialize::deserialize_into`]
123    /// into a slot contained within the owned sink.  To extract the final
124    /// value use [`take`](Self::take).
125    ///
126    /// The sink is allocated in the arena of the state (see
127    /// [`SinkHandle::arena`]).  If the owned sink outlives the
128    /// deserialization, the chunk of the arena it's in is freed when it's
129    /// dropped.
130    pub fn deserialize(state: &mut State) -> OwnedSink<'de, T> {
131        OwnedSink::with(T::deserialize_into, state)
132    }
133}
134
135impl<'de, T> OwnedSink<'de, T> {
136    /// Creates a new owned sink that deserializes with an adapter.
137    ///
138    /// This is like [`deserialize`](Self::deserialize) but begins the
139    /// deserialization with
140    /// [`DeserializeAs::deserialize_into_as`] of the adapter `A`.
141    pub fn deserialize_as<A: DeserializeAs<'de, T>>(state: &mut State) -> OwnedSink<'de, T> {
142        OwnedSink::with(A::deserialize_into_as, state)
143    }
144
145    /// Creates an owned sink whose slot starts out with a value.
146    pub(crate) fn with_slot(
147        slot: Option<T>,
148        make: for<'x> fn(&'x mut Option<T>, &mut State) -> SinkHandle<'x, 'de>,
149        state: &mut State,
150    ) -> OwnedSink<'de, T> {
151        let storage = ArenaBox::new(slot, &mut state.arena);
152        // SAFETY: like in `with`
153        let sink = unsafe {
154            let slot = unbounded(storage.ptr().as_ptr());
155            core::mem::transmute::<SinkHandle<'_, 'de>, SinkHandle<'de, 'de>>(make(slot, state))
156        };
157        OwnedSink {
158            storage,
159            sink: ManuallyDrop::new(sink),
160        }
161    }
162
163    /// Creates an owned sink without a value that ignores everything.
164    pub(crate) fn null(state: &mut State) -> OwnedSink<'de, T> {
165        OwnedSink::with(|_, _| SinkHandle::null(), state)
166    }
167
168    pub(crate) fn with(
169        make: for<'x> fn(&'x mut Option<T>, &mut State) -> SinkHandle<'x, 'de>,
170        state: &mut State,
171    ) -> OwnedSink<'de, T> {
172        let storage = ArenaBox::new(None, &mut state.arena);
173        // SAFETY: the storage is in the arena and not moved.  The sink is
174        // dropped before the storage is accessed again or freed.
175        let sink = unsafe {
176            let slot = unbounded(storage.ptr().as_ptr());
177            core::mem::transmute::<SinkHandle<'_, 'de>, SinkHandle<'de, 'de>>(make(slot, state))
178        };
179        OwnedSink {
180            storage,
181            sink: ManuallyDrop::new(sink),
182        }
183    }
184
185    /// Creates an owned sink that updates a value.
186    ///
187    /// The value is moved into the owned sink and updated with
188    /// [`Deserialize::deserialize_update`].  It can be taken out again with
189    /// [`take`](Self::take), also if the update failed.
190    pub(crate) fn update(value: T, state: &mut State) -> OwnedSink<'de, T>
191    where
192        T: Deserialize<'de>,
193    {
194        let storage = ArenaBox::new(Some(value), &mut state.arena);
195        // SAFETY: like in `with`, the storage is in the arena and not
196        // moved.  The value in it is not replaced while the sink exists, the
197        // sink is dropped before the storage is accessed again or freed.
198        let sink = unsafe {
199            let slot = unbounded(storage.ptr().as_ptr());
200            let value = slot.as_mut().unwrap_unchecked();
201            core::mem::transmute::<SinkHandle<'_, 'de>, SinkHandle<'de, 'de>>(
202                T::deserialize_update(value, state),
203            )
204        };
205        OwnedSink {
206            storage,
207            sink: ManuallyDrop::new(sink),
208        }
209    }
210
211    /// Immutably borrows the sink.
212    #[allow(clippy::should_implement_trait)]
213    pub fn borrow(&self) -> &(dyn Sink<'de> + '_) {
214        &*self.sink
215    }
216
217    /// Mutably borrows the sink.
218    #[allow(clippy::should_implement_trait)]
219    pub fn borrow_mut(&mut self) -> &mut (dyn Sink<'de> + '_) {
220        &mut *self.sink
221    }
222
223    /// Takes the value produced by the sink.
224    ///
225    /// This finishes the use of the sink.  After calling this method the
226    /// sink will drop all values it receives.
227    pub fn take(&mut self) -> Option<T> {
228        // the sink borrows from the storage, so it needs to go first.
229        *self.sink = SinkHandle::null();
230        self.storage.get_mut().take()
231    }
232}
233
234impl<'de, T> Drop for OwnedSink<'de, T> {
235    fn drop(&mut self) {
236        // SAFETY: the sink is never used again and dropped before the
237        // storage it borrows from.
238        unsafe {
239            ManuallyDrop::drop(&mut self.sink);
240        }
241    }
242}
243
244/// A [`DeserializeDriver`] which owns the value it deserializes.
245///
246/// A [`DeserializeDriver`] borrows the slot of the value it deserializes,
247/// which means that it cannot be held together with the slot, for instance
248/// in a struct that deserializes a value from input which arrives over
249/// time.  This bundles a driver with its slot.  The driver is lent out with
250/// [`with`](Self::with) and the value is taken with
251/// [`finish`](Self::finish):
252///
253/// ```
254/// use deser::de::OwnedDriver;
255/// use deser::Event;
256///
257/// let mut driver = OwnedDriver::<Vec<u32>>::new();
258/// driver.with(|driver| driver.emit(Event::seq_start())).unwrap();
259/// // ... later, when more input arrived
260/// driver.with(|driver| {
261///     driver.emit(1u64)?;
262///     driver.emit(Event::SeqEnd)
263/// }).unwrap();
264/// assert_eq!(driver.finish().unwrap(), [1]);
265/// ```
266pub struct OwnedDriver<'de, T> {
267    // The driver borrows from the storage.  It's dropped before the
268    // storage is accessed (in `finish`) or dropped.  The lifetime of the
269    // borrow is erased (to `'de` as the driver cannot outlive that).
270    driver: ManuallyDrop<DeserializeDriver<'de, 'de>>,
271    storage: NonuniqueBox<Option<T>>,
272}
273
274impl<'de, T: Deserialize<'de>> OwnedDriver<'de, T> {
275    /// Creates a driver for a value.
276    pub fn new() -> OwnedDriver<'de, T> {
277        let storage = NonuniqueBox::new(None);
278        // SAFETY: the storage is heap allocated and not moved.  The driver
279        // is dropped before the storage is accessed again or freed.
280        let driver = unsafe {
281            let slot = &mut *storage.ptr.as_ptr();
282            core::mem::transmute::<DeserializeDriver<'_, 'de>, DeserializeDriver<'de, 'de>>(
283                DeserializeDriver::new(slot),
284            )
285        };
286        OwnedDriver {
287            driver: ManuallyDrop::new(driver),
288            storage,
289        }
290    }
291}
292
293impl<'de, T: Deserialize<'de>> Default for OwnedDriver<'de, T> {
294    fn default() -> OwnedDriver<'de, T> {
295        OwnedDriver::new()
296    }
297}
298
299impl<'de, T> OwnedDriver<'de, T> {
300    /// Invokes a function with the driver.
301    ///
302    /// The function has to accept a driver of any lifetime which ensures
303    /// that it cannot keep the driver or replace it.
304    pub fn with<R, F>(&mut self, f: F) -> R
305    where
306        F: for<'a> FnOnce(&mut DeserializeDriver<'a, 'de>) -> R,
307    {
308        f(&mut self.driver)
309    }
310
311    /// Returns a reference to the driver.
312    pub fn driver(&self) -> &DeserializeDriver<'_, 'de> {
313        &self.driver
314    }
315
316    /// Finishes the deserialization and returns the value.
317    ///
318    /// Fails with [`ErrorKind::EndOfFile`] if the value is incomplete.
319    pub fn finish(self) -> Result<T, Error> {
320        let mut this = ManuallyDrop::new(self);
321        // SAFETY: the driver is dropped before the storage it borrows from
322        // is accessed.  The storage is moved out of the forgotten value
323        // exactly once.
324        let mut storage = unsafe {
325            ManuallyDrop::drop(&mut this.driver);
326            core::ptr::read(&this.storage)
327        };
328        storage
329            .take()
330            .ok_or_else(|| Error::new(ErrorKind::EndOfFile, "unexpected end of input"))
331    }
332}
333
334impl<'de, T> Drop for OwnedDriver<'de, T> {
335    fn drop(&mut self) {
336        // SAFETY: the driver is never used again and dropped before the
337        // storage it borrows from.
338        unsafe {
339            ManuallyDrop::drop(&mut self.driver);
340        }
341    }
342}