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