use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::hash::BuildHasher;
use std::hash::Hash;
use std::mem::{take, MaybeUninit};
use crate::de::{Deserialize, DeserializerState, OwnedSink, Sink, SinkHandle};
use crate::descriptors::{Descriptor, NamedDescriptor, UnorderedNamedDescriptor};
use crate::error::{Error, ErrorKind};
use crate::event::Atom;
make_slot_wrapper!(SlotWrapper);
macro_rules! deserialize {
($ty:ty) => {
impl Deserialize for $ty {
fn deserialize_into(out: &mut Option<Self>) -> SinkHandle {
SlotWrapper::make_handle(out)
}
}
};
}
impl Sink for SlotWrapper<()> {
fn descriptor(&self) -> &dyn Descriptor {
static DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "null" };
&DESCRIPTOR
}
fn atom(&mut self, atom: Atom, state: &DeserializerState) -> Result<(), Error> {
match atom {
Atom::Null => {
**self = Some(());
Ok(())
}
other => self.unexpected_atom(other, state),
}
}
}
deserialize!(());
impl Sink for SlotWrapper<bool> {
fn descriptor(&self) -> &dyn Descriptor {
static DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "bool" };
&DESCRIPTOR
}
fn atom(&mut self, atom: Atom, state: &DeserializerState) -> Result<(), Error> {
match atom {
Atom::Bool(value) => {
**self = Some(value);
Ok(())
}
other => self.unexpected_atom(other, state),
}
}
}
deserialize!(bool);
impl Sink for SlotWrapper<String> {
fn descriptor(&self) -> &dyn Descriptor {
static DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "string" };
&DESCRIPTOR
}
fn atom(&mut self, atom: Atom, state: &DeserializerState) -> Result<(), Error> {
match atom {
Atom::Str(value) => {
**self = Some(value.into_owned());
Ok(())
}
other => self.unexpected_atom(other, state),
}
}
}
deserialize!(String);
macro_rules! int_sink {
($ty:ty) => {
impl Sink for SlotWrapper<$ty> {
fn descriptor(&self) -> &dyn Descriptor {
static DESCRIPTOR: NamedDescriptor = NamedDescriptor {
name: stringify!($ty),
};
&DESCRIPTOR
}
fn atom(&mut self, atom: Atom, state: &DeserializerState) -> Result<(), Error> {
match atom {
Atom::U64(value) => {
let truncated = value as $ty;
if truncated as u64 == value {
**self = Some(truncated);
Ok(())
} else {
Err(Error::new(
ErrorKind::OutOfRange,
"value out of range for type",
))
}
}
Atom::I64(value) => {
let truncated = value as $ty;
if truncated as i64 == value {
**self = Some(truncated);
Ok(())
} else {
Err(Error::new(
ErrorKind::OutOfRange,
"value out of range for type",
))
}
}
other => self.unexpected_atom(other, state),
}
}
}
};
}
int_sink!(u8);
impl Deserialize for u8 {
fn deserialize_into(out: &mut Option<Self>) -> SinkHandle {
SlotWrapper::make_handle(out)
}
unsafe fn __private_is_bytes() -> bool {
true
}
}
int_sink!(u16);
deserialize!(u16);
int_sink!(u32);
deserialize!(u32);
int_sink!(u64);
deserialize!(u64);
int_sink!(i8);
deserialize!(i8);
int_sink!(i16);
deserialize!(i16);
int_sink!(i32);
deserialize!(i32);
int_sink!(i64);
deserialize!(i64);
int_sink!(isize);
deserialize!(isize);
int_sink!(usize);
deserialize!(usize);
impl Sink for SlotWrapper<char> {
fn descriptor(&self) -> &dyn Descriptor {
static DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "char" };
&DESCRIPTOR
}
fn atom(&mut self, atom: Atom, state: &DeserializerState) -> Result<(), Error> {
match atom {
Atom::Char(value) => {
**self = Some(value);
Ok(())
}
Atom::Str(ref s) => {
let mut chars = s.chars();
if let Some(first_char) = chars.next() {
if chars.next().is_none() {
**self = Some(first_char);
return Ok(());
}
}
Err(atom.unexpected_error(&self.expecting()))
}
other => self.unexpected_atom(other, state),
}
}
}
deserialize!(char);
macro_rules! float_sink {
($ty:ty) => {
impl Sink for SlotWrapper<$ty> {
fn descriptor(&self) -> &dyn Descriptor {
static DESCRIPTOR: NamedDescriptor = NamedDescriptor {
name: stringify!($ty),
};
&DESCRIPTOR
}
fn atom(&mut self, atom: Atom, state: &DeserializerState) -> Result<(), Error> {
match atom {
Atom::U64(value) => {
**self = Some(value as $ty);
Ok(())
}
Atom::I64(value) => {
**self = Some(value as $ty);
Ok(())
}
Atom::F64(value) => {
**self = Some(value as $ty);
Ok(())
}
other => self.unexpected_atom(other, state),
}
}
}
};
}
float_sink!(f32);
deserialize!(f32);
float_sink!(f64);
deserialize!(f64);
impl<T: Deserialize> Deserialize for Vec<T> {
fn deserialize_into(out: &mut Option<Self>) -> SinkHandle {
struct VecSink<'a, T> {
slot: &'a mut Option<Vec<T>>,
vec: Vec<T>,
element: Option<T>,
is_seq: bool,
}
impl<'a, T: 'a> VecSink<'a, T> {
fn flush(&mut self) {
if let Some(element) = self.element.take() {
self.vec.push(element);
}
}
}
impl<'a, T: Deserialize> Sink for VecSink<'a, T> {
fn descriptor(&self) -> &dyn Descriptor {
static SLICE_DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "vec" };
static BYTES_DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "bytes" };
if unsafe { T::__private_is_bytes() } {
&BYTES_DESCRIPTOR
} else {
&SLICE_DESCRIPTOR
}
}
fn atom(&mut self, atom: Atom, state: &DeserializerState) -> Result<(), Error> {
match atom {
Atom::Bytes(value) => unsafe {
if T::__private_is_bytes() {
*self.slot = Some(std::mem::transmute(value.into_owned()));
Ok(())
} else {
Err(Error::new(
ErrorKind::Unexpected,
format!("unexpected bytes, expected {}", self.expecting()),
))
}
},
other => self.unexpected_atom(other, state),
}
}
fn seq(&mut self, _state: &DeserializerState) -> Result<(), Error> {
self.is_seq = true;
Ok(())
}
fn next_value(&mut self, _state: &DeserializerState) -> Result<SinkHandle, Error> {
self.flush();
Ok(Deserialize::deserialize_into(&mut self.element))
}
fn finish(&mut self, _state: &DeserializerState) -> Result<(), Error> {
if self.is_seq {
self.flush();
*self.slot = Some(take(&mut self.vec));
}
Ok(())
}
}
SinkHandle::boxed(VecSink {
slot: out,
vec: Vec::new(),
element: None,
is_seq: false,
})
}
}
impl<K, V> Deserialize for BTreeMap<K, V>
where
K: Ord + Deserialize,
V: Deserialize,
{
fn deserialize_into(out: &mut Option<Self>) -> SinkHandle {
struct MapSink<'a, K: 'a, V: 'a> {
slot: &'a mut Option<BTreeMap<K, V>>,
map: BTreeMap<K, V>,
key: Option<K>,
value: Option<V>,
}
impl<'a, K, V> MapSink<'a, K, V>
where
K: Ord,
{
fn flush(&mut self) {
if let (Some(key), Some(value)) = (self.key.take(), self.value.take()) {
self.map.insert(key, value);
}
}
}
impl<'a, K, V> Sink for MapSink<'a, K, V>
where
K: Ord + Deserialize,
V: Deserialize,
{
fn descriptor(&self) -> &dyn Descriptor {
static DESCRIPTOR: UnorderedNamedDescriptor =
UnorderedNamedDescriptor { name: "map" };
&DESCRIPTOR
}
fn map(&mut self, _state: &DeserializerState) -> Result<(), Error> {
Ok(())
}
fn next_key(&mut self, _state: &DeserializerState) -> Result<SinkHandle, Error> {
self.flush();
Ok(Deserialize::deserialize_into(&mut self.key))
}
fn next_value(&mut self, _state: &DeserializerState) -> Result<SinkHandle, Error> {
Ok(Deserialize::deserialize_into(&mut self.value))
}
fn finish(&mut self, _state: &DeserializerState) -> Result<(), Error> {
self.flush();
*self.slot = Some(take(&mut self.map));
Ok(())
}
}
SinkHandle::boxed(MapSink {
slot: out,
map: BTreeMap::new(),
key: None,
value: None,
})
}
}
impl<K, V, H> Deserialize for HashMap<K, V, H>
where
K: Hash + Eq + Deserialize,
V: Deserialize,
H: BuildHasher + Default,
{
fn deserialize_into(out: &mut Option<Self>) -> SinkHandle {
struct MapSink<'a, K: 'a, V: 'a, H> {
slot: &'a mut Option<HashMap<K, V, H>>,
map: HashMap<K, V, H>,
key: Option<K>,
value: Option<V>,
}
impl<'a, K, V, H> MapSink<'a, K, V, H>
where
K: Hash + Eq,
H: BuildHasher,
{
fn flush(&mut self) {
if let (Some(key), Some(value)) = (self.key.take(), self.value.take()) {
self.map.insert(key, value);
}
}
}
impl<'a, K, V, H> Sink for MapSink<'a, K, V, H>
where
K: Hash + Eq + Deserialize,
V: Deserialize,
H: BuildHasher + Default,
{
fn descriptor(&self) -> &dyn Descriptor {
static DESCRIPTOR: UnorderedNamedDescriptor =
UnorderedNamedDescriptor { name: "map" };
&DESCRIPTOR
}
fn next_key(&mut self, _state: &DeserializerState) -> Result<SinkHandle, Error> {
self.flush();
Ok(Deserialize::deserialize_into(&mut self.key))
}
fn next_value(&mut self, _state: &DeserializerState) -> Result<SinkHandle, Error> {
Ok(Deserialize::deserialize_into(&mut self.value))
}
fn finish(&mut self, _state: &DeserializerState) -> Result<(), Error> {
self.flush();
*self.slot = Some(take(&mut self.map));
Ok(())
}
}
SinkHandle::boxed(MapSink {
slot: out,
map: HashMap::default(),
key: None,
value: None,
})
}
}
impl<T: Deserialize + Ord> Deserialize for BTreeSet<T> {
fn deserialize_into(out: &mut Option<Self>) -> SinkHandle {
struct BTreeSetSink<'a, T> {
slot: &'a mut Option<BTreeSet<T>>,
set: BTreeSet<T>,
element: Option<T>,
}
impl<'a, T: 'a + Ord> BTreeSetSink<'a, T> {
fn flush(&mut self) {
if let Some(element) = self.element.take() {
self.set.insert(element);
}
}
}
impl<'a, T: Deserialize + Ord> Sink for BTreeSetSink<'a, T> {
fn descriptor(&self) -> &dyn Descriptor {
static DESCRIPTOR: UnorderedNamedDescriptor =
UnorderedNamedDescriptor { name: "BTreeSet" };
&DESCRIPTOR
}
fn seq(&mut self, _state: &DeserializerState) -> Result<(), Error> {
Ok(())
}
fn next_value(&mut self, _state: &DeserializerState) -> Result<SinkHandle, Error> {
self.flush();
Ok(Deserialize::deserialize_into(&mut self.element))
}
fn finish(&mut self, _state: &DeserializerState) -> Result<(), Error> {
self.flush();
*self.slot = Some(take(&mut self.set));
Ok(())
}
}
SinkHandle::boxed(BTreeSetSink {
slot: out,
set: BTreeSet::new(),
element: None,
})
}
}
impl<T, H> Deserialize for HashSet<T, H>
where
T: Deserialize + Hash + Eq,
H: BuildHasher + Default,
{
fn deserialize_into(out: &mut Option<Self>) -> SinkHandle {
struct HashSetSink<'a, T, H> {
slot: &'a mut Option<HashSet<T, H>>,
set: HashSet<T, H>,
element: Option<T>,
}
impl<'a, T, H> HashSetSink<'a, T, H>
where
T: Hash + Eq,
H: BuildHasher,
{
fn flush(&mut self) {
if let Some(element) = self.element.take() {
self.set.insert(element);
}
}
}
impl<'a, T, H> Sink for HashSetSink<'a, T, H>
where
T: Hash + Eq + Deserialize,
H: BuildHasher + Default,
{
fn descriptor(&self) -> &dyn Descriptor {
static DESCRIPTOR: UnorderedNamedDescriptor =
UnorderedNamedDescriptor { name: "HashSet" };
&DESCRIPTOR
}
fn seq(&mut self, _state: &DeserializerState) -> Result<(), Error> {
Ok(())
}
fn next_value(&mut self, _state: &DeserializerState) -> Result<SinkHandle, Error> {
self.flush();
Ok(Deserialize::deserialize_into(&mut self.element))
}
fn finish(&mut self, _state: &DeserializerState) -> Result<(), Error> {
self.flush();
*self.slot = Some(take(&mut self.set));
Ok(())
}
}
SinkHandle::boxed(HashSetSink {
slot: out,
set: HashSet::default(),
element: None,
})
}
}
impl<T> Deserialize for Option<T>
where
T: Deserialize,
{
fn deserialize_into(out: &mut Option<Self>) -> SinkHandle {
*out = Some(None);
let sink = Deserialize::deserialize_into(out.as_mut().unwrap());
match sink {
SinkHandle::Null(_) => sink,
sink => SinkHandle::boxed(NullIgnoringSink { sink }),
}
}
fn __private_initial_value() -> Option<Self> {
Some(None)
}
}
struct NullIgnoringSink<'a> {
sink: SinkHandle<'a>,
}
impl<'a> Sink for NullIgnoringSink<'a> {
fn atom(&mut self, atom: Atom, state: &DeserializerState) -> Result<(), Error> {
match atom {
Atom::Null => Ok(()),
other => self.sink.atom(other, state),
}
}
fn map(&mut self, state: &DeserializerState) -> Result<(), Error> {
self.sink.map(state)
}
fn seq(&mut self, state: &DeserializerState) -> Result<(), Error> {
self.sink.seq(state)
}
fn next_key(&mut self, state: &DeserializerState) -> Result<SinkHandle, Error> {
self.sink.next_key(state)
}
fn next_value(&mut self, state: &DeserializerState) -> Result<SinkHandle, Error> {
self.sink.next_value(state)
}
fn descriptor(&self) -> &dyn Descriptor {
self.sink.descriptor()
}
}
macro_rules! deserialize_for_tuple {
() => ();
($($name:ident,)+) => (
impl<$($name: Deserialize),*> Deserialize for ($($name,)*) {
fn deserialize_into(out: &mut Option<Self>) -> SinkHandle {
#![allow(non_snake_case)]
struct TupleSink<'a, $($name,)*> {
slot: &'a mut Option<($($name,)*)>,
index: usize,
$(
$name: Option<$name>,
)*
}
impl<'a, $($name: Deserialize,)*> Sink for TupleSink<'a, $($name,)*> {
fn descriptor(&self) -> &dyn Descriptor {
static DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "tuple" };
&DESCRIPTOR
}
fn seq(&mut self, _state: &DeserializerState) -> Result<(), Error> {
Ok(())
}
fn next_value(&mut self, _state: &DeserializerState) -> Result<SinkHandle, Error> {
let __index = self.index;
self.index += 1;
let mut __counter = 0;
$(
if __index == __counter {
return Ok(Deserialize::deserialize_into(&mut self.$name));
}
__counter += 1;
)*
Err(Error::new(ErrorKind::WrongLength, "too many elements in tuple"))
}
fn finish(&mut self, _state: &DeserializerState) -> Result<(), Error> {
*self.slot = Some(($(
self.$name
.take()
.ok_or_else(|| Error::new(ErrorKind::WrongLength, "not enough elements in tuple"))?,
)*));
Ok(())
}
}
SinkHandle::boxed(TupleSink {
slot: out,
index: 0,
$(
$name: None,
)*
})
}
}
deserialize_for_tuple_peel!($($name,)*);
)
}
macro_rules! deserialize_for_tuple_peel {
($name:ident, $($other:ident,)*) => (deserialize_for_tuple!($($other,)*);)
}
deserialize_for_tuple! { T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, }
impl<T: Deserialize, const N: usize> Deserialize for [T; N] {
fn deserialize_into(out: &mut Option<Self>) -> SinkHandle {
struct ArraySink<'a, T, const N: usize> {
slot: &'a mut Option<[T; N]>,
buffer: Option<[MaybeUninit<T>; N]>,
element: Option<T>,
index: usize,
is_seq: bool,
}
impl<'a, T, const N: usize> ArraySink<'a, T, N> {
unsafe fn flush(&mut self) {
if let Some(element) = self.element.take() {
let buffer = self.buffer.as_mut().unwrap();
buffer[self.index].write(element);
self.index += 1;
}
}
}
impl<'a, T, const N: usize> Drop for ArraySink<'a, T, N> {
fn drop(&mut self) {
if std::mem::needs_drop::<T>() {
if let Some(arr) = &mut self.buffer {
for elem in &mut arr[0..self.index] {
unsafe {
std::ptr::drop_in_place(elem.as_mut_ptr());
}
}
}
}
}
}
impl<'a, T: Deserialize + 'a, const N: usize> Sink for ArraySink<'a, T, N> {
fn descriptor(&self) -> &dyn Descriptor {
static DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "array" };
&DESCRIPTOR
}
fn atom(&mut self, atom: Atom, state: &DeserializerState) -> Result<(), Error> {
match atom {
Atom::Bytes(value) => {
if unsafe { T::__private_is_bytes() } {
if value.len() == N {
*self.slot = Some(unsafe {
let mut rv = MaybeUninit::<[T; N]>::uninit();
std::ptr::copy_nonoverlapping(
value.as_ptr() as *const T,
rv.as_mut_ptr() as *mut T,
N,
);
rv.assume_init()
});
Ok(())
} else {
Err(Error::new(
ErrorKind::WrongLength,
"byte array of wrong length",
))
}
} else {
Err(Error::new(
ErrorKind::Unexpected,
format!("unexpected bytes, expected {}", self.expecting()),
))
}
}
other => self.unexpected_atom(other, state),
}
}
fn seq(&mut self, _state: &DeserializerState) -> Result<(), Error> {
self.is_seq = true;
Ok(())
}
fn next_value(&mut self, _state: &DeserializerState) -> Result<SinkHandle, Error> {
unsafe {
self.flush();
}
if self.index >= N {
Err(Error::new(
ErrorKind::WrongLength,
"too many elements in array",
))
} else {
Ok(Deserialize::deserialize_into(&mut self.element))
}
}
fn finish(&mut self, _state: &DeserializerState) -> Result<(), Error> {
if !self.is_seq {
return Ok(());
}
unsafe {
self.flush();
}
if self.index != N {
Err(Error::new(
ErrorKind::WrongLength,
"not enough elements in array",
))
} else {
*self.slot = Some(unsafe {
self.buffer.take().unwrap().as_ptr().cast::<[T; N]>().read()
});
Ok(())
}
}
}
SinkHandle::boxed(ArraySink {
slot: out,
buffer: Some(unsafe { MaybeUninit::uninit().assume_init() }),
element: None,
index: 0,
is_seq: false,
})
}
}
impl<T: Deserialize> Deserialize for Box<T> {
fn deserialize_into(out: &mut Option<Self>) -> SinkHandle {
struct BoxSink<'a, T> {
out: &'a mut Option<Box<T>>,
sink: OwnedSink<T>,
}
impl<'a, T: Deserialize> Sink for BoxSink<'a, T> {
fn atom(&mut self, atom: Atom, state: &DeserializerState) -> Result<(), Error> {
self.sink.borrow_mut().atom(atom, state)
}
fn map(&mut self, state: &DeserializerState) -> Result<(), Error> {
self.sink.borrow_mut().map(state)
}
fn seq(&mut self, state: &DeserializerState) -> Result<(), Error> {
self.sink.borrow_mut().seq(state)
}
fn next_key(&mut self, state: &DeserializerState) -> Result<SinkHandle, Error> {
self.sink.borrow_mut().next_key(state)
}
fn next_value(&mut self, state: &DeserializerState) -> Result<SinkHandle, Error> {
self.sink.borrow_mut().next_value(state)
}
fn value_for_key(
&mut self,
key: &str,
state: &DeserializerState,
) -> Result<Option<SinkHandle>, Error> {
self.sink.borrow_mut().value_for_key(key, state)
}
fn finish(&mut self, state: &DeserializerState) -> Result<(), Error> {
self.sink.borrow_mut().finish(state)?;
*self.out = self.sink.take().map(Box::new);
Ok(())
}
fn descriptor(&self) -> &dyn Descriptor {
self.sink.borrow().descriptor()
}
fn expecting(&self) -> std::borrow::Cow<'_, str> {
self.sink.borrow().expecting()
}
}
SinkHandle::boxed(BoxSink {
out,
sink: OwnedSink::<T>::deserialize(),
})
}
}