use alloc::boxed::Box;
use core::mem::ManuallyDrop;
use core::ops::{Deref, DerefMut};
use core::ptr::NonNull;
use crate::State;
use crate::arena::ArenaBox;
use crate::de::{Deserialize, DeserializeDriver, Sink, SinkHandle};
use crate::error::{Error, ErrorKind};
struct NonuniqueBox<T: ?Sized> {
ptr: NonNull<T>,
}
unsafe impl<T: ?Sized + Send> Send for NonuniqueBox<T> {}
impl<T> NonuniqueBox<T> {
pub(crate) fn new(value: T) -> Self {
NonuniqueBox::from(Box::new(value))
}
}
impl<T: ?Sized> From<Box<T>> for NonuniqueBox<T> {
fn from(boxed: Box<T>) -> Self {
let ptr = Box::into_raw(boxed);
let ptr = unsafe { NonNull::new_unchecked(ptr) };
NonuniqueBox { ptr }
}
}
impl<T: ?Sized> Deref for NonuniqueBox<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { self.ptr.as_ref() }
}
}
impl<T: ?Sized> DerefMut for NonuniqueBox<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { self.ptr.as_mut() }
}
}
impl<T: ?Sized> Drop for NonuniqueBox<T> {
fn drop(&mut self) {
let ptr = self.ptr.as_ptr();
let _ = unsafe { Box::from_raw(ptr) };
}
}
unsafe fn unbounded<'x, X>(ptr: *mut X) -> &'x mut X {
unsafe { &mut *ptr }
}
pub struct OwnedSink<'de, T> {
storage: ArenaBox<Option<T>>,
sink: ManuallyDrop<SinkHandle<'de, 'de>>,
}
impl<'de, T: Deserialize<'de>> OwnedSink<'de, T> {
pub fn deserialize(state: &mut State) -> OwnedSink<'de, T> {
OwnedSink::with(T::deserialize_into, state)
}
}
impl<'de, T: Send> OwnedSink<'de, T> {
pub fn deserialize_as<A: Deserialize<'de, T>>(state: &mut State) -> OwnedSink<'de, T> {
OwnedSink::with(A::deserialize_into, state)
}
}
impl<'de, T> OwnedSink<'de, T> {
pub(crate) fn with_slot(
slot: Option<T>,
make: for<'x> fn(&'x mut Option<T>, &mut State) -> SinkHandle<'x, 'de>,
state: &mut State,
) -> OwnedSink<'de, T> {
let storage = ArenaBox::new(slot, &mut state.arena);
let sink = unsafe {
let slot = unbounded(storage.ptr().as_ptr());
core::mem::transmute::<SinkHandle<'_, 'de>, SinkHandle<'de, 'de>>(make(slot, state))
};
OwnedSink {
storage,
sink: ManuallyDrop::new(sink),
}
}
pub(crate) fn null(state: &mut State) -> OwnedSink<'de, T> {
OwnedSink::with(|_, _| SinkHandle::null(), state)
}
pub(crate) fn with(
make: for<'x> fn(&'x mut Option<T>, &mut State) -> SinkHandle<'x, 'de>,
state: &mut State,
) -> OwnedSink<'de, T> {
let storage = ArenaBox::new(None, &mut state.arena);
let sink = unsafe {
let slot = unbounded(storage.ptr().as_ptr());
core::mem::transmute::<SinkHandle<'_, 'de>, SinkHandle<'de, 'de>>(make(slot, state))
};
OwnedSink {
storage,
sink: ManuallyDrop::new(sink),
}
}
pub(crate) fn update(
value: T,
update: for<'x> fn(&'x mut T, &mut State) -> SinkHandle<'x, 'de>,
state: &mut State,
) -> OwnedSink<'de, T> {
let storage = ArenaBox::new(Some(value), &mut state.arena);
let sink = unsafe {
let slot = unbounded(storage.ptr().as_ptr());
let value = slot.as_mut().unwrap_unchecked();
core::mem::transmute::<SinkHandle<'_, 'de>, SinkHandle<'de, 'de>>(update(value, state))
};
OwnedSink {
storage,
sink: ManuallyDrop::new(sink),
}
}
pub fn get(&self) -> &(dyn Sink<'de> + '_) {
&*self.sink
}
pub fn get_mut(&mut self) -> &mut (dyn Sink<'de> + '_) {
&mut *self.sink
}
pub fn take(&mut self) -> Option<T> {
*self.sink = SinkHandle::null();
self.storage.get_mut().take()
}
}
impl<'de, T> Drop for OwnedSink<'de, T> {
fn drop(&mut self) {
unsafe {
ManuallyDrop::drop(&mut self.sink);
}
}
}
pub struct OwnedDriver<'de, T> {
driver: ManuallyDrop<DeserializeDriver<'de, 'de>>,
storage: NonuniqueBox<Option<T>>,
}
impl<'de, T: Deserialize<'de>> OwnedDriver<'de, T> {
pub fn new() -> OwnedDriver<'de, T> {
let storage = NonuniqueBox::new(None);
let driver = unsafe {
let slot = &mut *storage.ptr.as_ptr();
core::mem::transmute::<DeserializeDriver<'_, 'de>, DeserializeDriver<'de, 'de>>(
DeserializeDriver::new(slot),
)
};
OwnedDriver {
driver: ManuallyDrop::new(driver),
storage,
}
}
}
impl<'de, T: Deserialize<'de>> Default for OwnedDriver<'de, T> {
fn default() -> OwnedDriver<'de, T> {
OwnedDriver::new()
}
}
impl<'de, T> OwnedDriver<'de, T> {
pub fn with<R, F>(&mut self, f: F) -> R
where
F: for<'a> FnOnce(&mut DeserializeDriver<'a, 'de>) -> R,
{
f(&mut self.driver)
}
pub fn finish(self) -> Result<T, Error> {
let mut this = ManuallyDrop::new(self);
let mut storage = unsafe {
ManuallyDrop::drop(&mut this.driver);
core::ptr::read(&this.storage)
};
storage
.take()
.ok_or_else(|| Error::new(ErrorKind::EndOfFile, "unexpected end of input"))
}
}
impl<'de, T> Drop for OwnedDriver<'de, T> {
fn drop(&mut self) {
unsafe {
ManuallyDrop::drop(&mut self.driver);
}
}
}