use alloc::boxed::Box;
use alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
use alloc::sync::Arc;
use alloc::vec::Vec;
#[cfg(feature = "std")]
use core::hash::BuildHasher;
use core::marker::PhantomData;
#[cfg(feature = "std")]
use std::collections::{HashMap, HashSet};
use crate::State;
use crate::adapters::SerializeAs;
use crate::error::Error;
use crate::event::{Atom, Bytes, ContainerShape};
use crate::ser::{
Begin, Chunk, Describe, IndexedSeq, IndexedSeqEmitter, MapEmitter, SeqEmitter, Serialize,
SerializeHandle,
};
#[repr(transparent)]
pub struct SerializeAsRef<A, T: ?Sized> {
_marker: PhantomData<fn() -> A>,
value: T,
}
impl<A, T: ?Sized> SerializeAsRef<A, T> {
#[inline(always)]
pub fn new(value: &T) -> &SerializeAsRef<A, T> {
unsafe { &*(value as *const T as *const SerializeAsRef<A, T>) }
}
#[inline(always)]
pub fn get(&self) -> &T {
&self.value
}
}
impl<A: SerializeAs<T>, T: ?Sized + Sync> Serialize for SerializeAsRef<A, T> {
#[inline]
fn serialize(&self, state: &mut State) -> Result<Chunk<'_>, Error> {
A::serialize_as(&self.value, state)
}
#[inline]
fn finish(&self, state: &mut State) -> Result<(), Error> {
A::finish_as(&self.value, state)
}
#[inline]
fn is_optional(&self) -> bool {
A::is_optional_as(&self.value)
}
#[inline]
fn container_shape(&self) -> ContainerShape {
A::container_shape_as(&self.value)
}
#[inline]
fn describe(&self, d: &mut dyn Describe) {
A::describe_as(&self.value, d)
}
#[inline]
fn __private_begin(&self, state: &mut State) -> Result<Begin<'_>, Error> {
A::__private_begin_as(&self.value, state)
}
}
#[inline(always)]
pub(crate) fn handle_as<A: SerializeAs<T>, T: Sync>(value: &T) -> SerializeHandle<'_> {
SerializeHandle::to(SerializeAsRef::<A, T>::new(value))
}
#[allow(clippy::type_complexity)]
pub(crate) struct IterEmitter<'a, I, A>(
pub(crate) I,
pub(crate) core::marker::PhantomData<(&'a (), fn() -> A)>,
);
impl<'a, I, T, A> SeqEmitter for IterEmitter<'a, I, A>
where
I: Iterator<Item = &'a T> + Send,
T: Sync + 'a,
A: SerializeAs<T>,
{
fn next(&mut self, _state: &mut State) -> Result<Option<SerializeHandle<'_>>, Error> {
Ok(self.0.next().map(handle_as::<A, T>))
}
}
pub(crate) struct MapIterEmitter<'a, I, V, KA, VA> {
pub(crate) iter: I,
pub(crate) value: Option<&'a V>,
pub(crate) _marker: core::marker::PhantomData<fn() -> (KA, VA)>,
}
impl<'a, I, K, V, KA, VA> MapEmitter for MapIterEmitter<'a, I, V, KA, VA>
where
I: Iterator<Item = (&'a K, &'a V)> + Send,
K: Sync + 'a,
V: Sync + 'a,
KA: SerializeAs<K>,
VA: SerializeAs<V>,
{
fn next_key(&mut self, _state: &mut State) -> Result<Option<SerializeHandle<'_>>, Error> {
Ok(self.iter.next().map(|(k, v)| {
self.value = Some(v);
handle_as::<KA, K>(k)
}))
}
fn next_value(&mut self, _state: &mut State) -> Result<SerializeHandle<'_>, Error> {
Ok(handle_as::<VA, V>(self.value.unwrap()))
}
}
impl<T: Sync, A: SerializeAs<T>> SerializeAs<Option<T>> for Option<A> {
fn serialize_as<'a>(value: &'a Option<T>, state: &mut State) -> Result<Chunk<'a>, Error> {
match value {
Some(value) => A::serialize_as(value, state),
None => Ok(Chunk::Atom(Atom::Null)),
}
}
fn finish_as(value: &Option<T>, state: &mut State) -> Result<(), Error> {
match value {
Some(value) => A::finish_as(value, state),
None => Ok(()),
}
}
fn is_optional_as(value: &Option<T>) -> bool {
value.is_none()
}
fn container_shape_as(value: &Option<T>) -> ContainerShape {
match value {
Some(value) => A::container_shape_as(value),
None => ContainerShape::new(),
}
}
fn describe_as(value: &Option<T>, d: &mut dyn Describe) {
match value {
Some(value) => {
d.some();
A::describe_as(value, d);
}
None => d.none(),
}
}
#[inline]
fn __private_begin_as<'a>(value: &'a Option<T>, state: &mut State) -> Result<Begin<'a>, Error> {
match value {
Some(value) => A::__private_begin_as(value, state),
None => Ok(Begin::chunk(
Chunk::Atom(Atom::Null),
ContainerShape::new(),
false,
)),
}
}
}
macro_rules! serialize_as_pointer {
($([$($gen:tt)*] $ty:ty => $adapter:ty, $inner:ty, $inner_adapter:ty;)*) => {
$(
impl<$($gen)*> SerializeAs<$ty> for $adapter {
fn serialize_as<'a>(value: &'a $ty, state: &mut State) -> Result<Chunk<'a>, Error> {
<$inner_adapter as SerializeAs<$inner>>::serialize_as(value, state)
}
fn finish_as(value: &$ty, state: &mut State) -> Result<(), Error> {
<$inner_adapter as SerializeAs<$inner>>::finish_as(value, state)
}
fn is_optional_as(value: &$ty) -> bool {
<$inner_adapter as SerializeAs<$inner>>::is_optional_as(value)
}
fn container_shape_as(value: &$ty) -> ContainerShape {
<$inner_adapter as SerializeAs<$inner>>::container_shape_as(value)
}
fn describe_as(value: &$ty, d: &mut dyn Describe) {
<$inner_adapter as SerializeAs<$inner>>::describe_as(value, d)
}
#[inline]
fn __private_begin_as<'a>(value: &'a $ty, state: &mut State) -> Result<Begin<'a>, Error> {
<$inner_adapter as SerializeAs<$inner>>::__private_begin_as(value, state)
}
}
)*
};
}
serialize_as_pointer! {
[T: Sync, A: SerializeAs<T>] Box<T> => Box<A>, T, A;
[T: Send + Sync, A: SerializeAs<T>] Arc<T> => Arc<A>, T, A;
[T: Sync, A: SerializeAs<T>] Box<[T]> => Box<[A]>, [T], [A];
[T: Send + Sync, A: SerializeAs<T>] Arc<[T]> => Arc<[A]>, [T], [A];
}
macro_rules! serialize_as_iter_seq {
($($ty:ident),*) => {
$(
impl<T: Sync, A: SerializeAs<T>> SerializeAs<$ty<T>> for $ty<A> {
fn serialize_as<'a>(value: &'a $ty<T>, state: &mut State) -> Result<Chunk<'a>, Error> {
Ok(Chunk::seq(IterEmitter::<'_, _, A>(
value.iter(),
core::marker::PhantomData,
), state))
}
fn container_shape_as(value: &$ty<T>) -> ContainerShape {
ContainerShape::new().with_len(value.len())
}
#[inline]
fn __private_begin_as<'a>(value: &'a $ty<T>, state: &mut State) -> Result<Begin<'a>, Error> {
let shape = Self::container_shape_as(value);
Ok(Begin::chunk(Self::serialize_as(value, state)?, shape, false))
}
}
)*
};
}
serialize_as_iter_seq!(VecDeque, LinkedList, BinaryHeap);
macro_rules! serialize_as_slice {
($([$($gen:tt)*] $ty:ty => $adapter:ty;)*) => {
$(
impl<$($gen)*> $crate::ser::IndexedSeq
for $crate::adapters::ser_impls::SerializeAsRef<$adapter, $ty>
{
#[inline]
fn element(
&self,
index: usize,
_state: &mut $crate::State,
) -> Result<Option<$crate::ser::SerializeHandle<'_>>, $crate::Error> {
Ok(self.get()[..]
.get(index)
.map($crate::adapters::ser_impls::handle_as::<A, T>))
}
}
impl<$($gen)*> $crate::adapters::SerializeAs<$ty> for $adapter {
fn serialize_as<'a>(
value: &'a $ty,
state: &mut $crate::State,
) -> Result<$crate::ser::Chunk<'a>, $crate::Error> {
Ok(match A::__private_slice_as_bytes_as(&value[..]) {
Some(bytes) => {
$crate::ser::Chunk::Atom($crate::Atom::Bytes($crate::Bytes::new(bytes)))
}
None => $crate::ser::Chunk::seq($crate::ser::IndexedSeqEmitter::new(
$crate::adapters::ser_impls::SerializeAsRef::<$adapter, $ty>::new(
value,
),
), state),
})
}
fn container_shape_as(value: &$ty) -> $crate::ContainerShape {
$crate::ContainerShape::new().with_len(value.len())
}
#[inline]
fn __private_begin_as<'a>(
value: &'a $ty,
_state: &mut $crate::State,
) -> Result<$crate::ser::Begin<'a>, $crate::Error> {
let shape = Self::container_shape_as(value);
Ok(match A::__private_slice_as_bytes_as(&value[..]) {
Some(bytes) => $crate::ser::Begin::chunk(
$crate::ser::Chunk::Atom($crate::Atom::Bytes($crate::Bytes::new(bytes))),
shape,
false,
),
None => $crate::ser::Begin::indexed_seq(
$crate::adapters::ser_impls::SerializeAsRef::<$adapter, $ty>::new(value),
shape,
),
})
}
}
)*
};
}
#[allow(unused_imports)]
pub(crate) use serialize_as_slice;
serialize_as_slice! {
[T: Sync, A: SerializeAs<T>] Vec<T> => Vec<A>;
}
impl<T: Sync, A: SerializeAs<T>, const N: usize> IndexedSeq for SerializeAsRef<[A; N], [T; N]> {
#[inline]
fn element(
&self,
index: usize,
_state: &mut State,
) -> Result<Option<SerializeHandle<'_>>, Error> {
Ok(self.get().get(index).map(handle_as::<A, T>))
}
}
impl<T: Sync, A: SerializeAs<T>, const N: usize> SerializeAs<[T; N]> for [A; N] {
fn serialize_as<'a>(value: &'a [T; N], state: &mut State) -> Result<Chunk<'a>, Error> {
Ok(match A::__private_slice_as_bytes_as(value) {
Some(bytes) => Chunk::Atom(Atom::Bytes(Bytes::new(bytes))),
None => Chunk::seq(
IndexedSeqEmitter::new(SerializeAsRef::<[A; N], [T; N]>::new(value)),
state,
),
})
}
fn container_shape_as(value: &[T; N]) -> ContainerShape {
ContainerShape::new().with_len(value.len())
}
#[inline]
fn __private_begin_as<'a>(value: &'a [T; N], _state: &mut State) -> Result<Begin<'a>, Error> {
let shape = Self::container_shape_as(value);
Ok(match A::__private_slice_as_bytes_as(value) {
Some(bytes) => Begin::chunk(Chunk::Atom(Atom::Bytes(Bytes::new(bytes))), shape, false),
None => Begin::indexed_seq(SerializeAsRef::<[A; N], [T; N]>::new(value), shape),
})
}
}
impl<T: Sync, A: SerializeAs<T>> SerializeAs<[T]> for [A] {
fn serialize_as<'a>(value: &'a [T], state: &mut State) -> Result<Chunk<'a>, Error> {
Ok(match A::__private_slice_as_bytes_as(value) {
Some(bytes) => Chunk::Atom(Atom::Bytes(Bytes::new(bytes))),
None => Chunk::seq(
IterEmitter::<'_, _, A>(value.iter(), core::marker::PhantomData),
state,
),
})
}
fn container_shape_as(value: &[T]) -> ContainerShape {
ContainerShape::new().with_len(value.len())
}
#[inline]
fn __private_begin_as<'a>(value: &'a [T], state: &mut State) -> Result<Begin<'a>, Error> {
let shape = Self::container_shape_as(value);
Ok(Begin::chunk(
Self::serialize_as(value, state)?,
shape,
false,
))
}
}
macro_rules! serialize_as_map {
($([$($gen:tt)*] $ty:ty => $adapter:ty, $order:ident;)*) => {
$(
impl<$($gen)*> $crate::adapters::SerializeAs<$ty> for $adapter
where
K: Sync,
V: Sync,
KA: $crate::adapters::SerializeAs<K>,
VA: $crate::adapters::SerializeAs<V>,
{
fn serialize_as<'a>(
value: &'a $ty,
state: &mut $crate::State,
) -> Result<$crate::ser::Chunk<'a>, $crate::Error> {
Ok($crate::ser::Chunk::map($crate::adapters::ser_impls::MapIterEmitter::<_, V, KA, VA> {
iter: value.iter(),
value: None,
_marker: core::marker::PhantomData,
}, state))
}
fn container_shape_as(value: &$ty) -> $crate::ContainerShape {
$crate::ContainerShape::new()
.with_order($crate::Order::$order)
.with_len(value.len())
}
#[inline]
fn __private_begin_as<'a>(
value: &'a $ty,
state: &mut $crate::State,
) -> Result<$crate::ser::Begin<'a>, $crate::Error> {
let shape = Self::container_shape_as(value);
Ok($crate::ser::Begin::chunk(
Self::serialize_as(value, state)?,
shape,
false,
))
}
}
)*
};
}
#[allow(unused_imports)]
pub(crate) use serialize_as_map;
serialize_as_map! {
[K, V, KA, VA] BTreeMap<K, V> => BTreeMap<KA, VA>, Sorted;
}
#[cfg(feature = "std")]
serialize_as_map! {
[K, V, H: BuildHasher + Sync, KA, VA] HashMap<K, V, H> => HashMap<KA, VA>, Arbitrary;
}
macro_rules! serialize_as_set {
($([$($gen:tt)*] $ty:ty => $adapter:ty, $order:ident;)*) => {
$(
impl<$($gen)*> $crate::adapters::SerializeAs<$ty> for $adapter
where
T: Sync,
A: $crate::adapters::SerializeAs<T>,
{
fn serialize_as<'a>(
value: &'a $ty,
state: &mut $crate::State,
) -> Result<$crate::ser::Chunk<'a>, $crate::Error> {
Ok($crate::ser::Chunk::seq($crate::adapters::ser_impls::IterEmitter::<'_, _, A>(
value.iter(),
core::marker::PhantomData,
), state))
}
fn container_shape_as(value: &$ty) -> $crate::ContainerShape {
$crate::ContainerShape::new()
.with_order($crate::Order::$order)
.with_len(value.len())
}
fn describe_as(_value: &$ty, d: &mut dyn $crate::ser::Describe) {
d.set();
}
#[inline]
fn __private_begin_as<'a>(
value: &'a $ty,
state: &mut $crate::State,
) -> Result<$crate::ser::Begin<'a>, $crate::Error> {
let shape = Self::container_shape_as(value);
Ok($crate::ser::Begin::chunk(
Self::serialize_as(value, state)?,
shape,
false,
))
}
}
)*
};
}
#[allow(unused_imports)]
pub(crate) use serialize_as_set;
serialize_as_set! {
[T, A] BTreeSet<T> => BTreeSet<A>, Sorted;
}
#[cfg(feature = "std")]
serialize_as_set! {
[T, H: BuildHasher + Sync, A] HashSet<T, H> => HashSet<A>, Arbitrary;
}
macro_rules! count_one {
($name:ident) => {
1
};
}
macro_rules! serialize_as_for_tuple {
() => ();
($(($name:ident, $adapter:ident),)+) => (
impl<$($name: Sync,)* $($adapter: SerializeAs<$name>),*> IndexedSeq
for SerializeAsRef<($($adapter,)*), ($($name,)*)>
{
#[allow(non_snake_case)]
fn element(&self, index: usize, _state: &mut State) -> Result<Option<SerializeHandle<'_>>, Error> {
let ($(ref $name,)*) = *self.get();
let mut __counter = 0;
$(
if index == __counter {
return Ok(Some(handle_as::<$adapter, $name>($name)));
}
__counter += 1;
)*
let _ = __counter;
Ok(None)
}
}
impl<$($name: Sync,)* $($adapter: SerializeAs<$name>),*> SerializeAs<($($name,)*)> for ($($adapter,)*) {
fn serialize_as<'a>(value: &'a ($($name,)*), state: &mut State) -> Result<Chunk<'a>, Error> {
Ok(Chunk::seq(IndexedSeqEmitter::new(SerializeAsRef::<($($adapter,)*), ($($name,)*)>::new(value)), state))
}
fn describe_as(_value: &($($name,)*), d: &mut dyn Describe) {
d.tuple();
}
fn container_shape_as(_value: &($($name,)*)) -> ContainerShape {
ContainerShape::new().with_len(0 $(+ count_one!($name))*)
}
#[inline]
fn __private_begin_as<'a>(value: &'a ($($name,)*), _state: &mut State) -> Result<Begin<'a>, Error> {
Ok(Begin::indexed_seq(
SerializeAsRef::<($($adapter,)*), ($($name,)*)>::new(value),
Self::container_shape_as(value),
))
}
}
serialize_as_for_tuple_peel!($(($name, $adapter),)*);
)
}
macro_rules! serialize_as_for_tuple_peel {
($first:tt, $($other:tt,)*) => (serialize_as_for_tuple!($($other,)*);)
}
serialize_as_for_tuple! {
(T1, A1), (T2, A2), (T3, A3), (T4, A4), (T5, A5), (T6, A6),
(T7, A7), (T8, A8), (T9, A9), (T10, A10), (T11, A11), (T12, A12),
}