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}