use alloc::borrow::Cow;
use alloc::vec::Vec;
use core::marker::PhantomData;
use crate::State;
use crate::adapters::Same;
use crate::de::{Deserialize, SinkHandle};
use crate::error::Error;
use crate::event::{Atom, ContainerShape};
use crate::ser::{Begin, Describe, Emit, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
#[non_exhaustive]
pub enum Layout {
#[default]
Auto,
Compact,
Expanded,
}
impl Layout {
#[inline]
pub fn of(state: &State) -> Layout {
state.event::<Layout>().copied().unwrap_or_default()
}
#[inline]
pub fn set(self, state: &mut State) {
*state.event_mut::<Layout>() = self;
}
}
pub trait Hint: 'static {
fn set(state: &mut State);
}
pub struct Hinted<H, A = Same>(PhantomData<fn() -> (H, A)>);
impl<T: ?Sized, H: Hint, A: Serialize<T>> Serialize<T> for Hinted<H, A> {
#[inline]
fn serialize<'a>(value: &'a T, state: &mut State) -> Result<Emit<'a>, Error> {
H::set(state);
A::serialize(value, state)
}
#[inline]
fn finish(value: &T, state: &mut State) -> Result<(), Error> {
A::finish(value, state)
}
#[inline]
fn is_optional(value: &T) -> bool {
A::is_optional(value)
}
#[inline]
fn container_shape(value: &T) -> ContainerShape {
A::container_shape(value)
}
fn describe(value: &T, d: &mut dyn Describe) {
A::describe(value, d)
}
#[inline]
fn __private_begin<'a>(value: &'a T, state: &mut State) -> Result<Begin<'a>, Error> {
H::set(state);
A::__private_begin(value, state)
}
#[inline]
fn __private_slice_as_bytes(val: &[T]) -> Option<Cow<'_, [u8]>>
where
T: Sized,
{
A::__private_slice_as_bytes(val)
}
}
impl<'de, T: Send, H: Hint, A: Deserialize<'de, T>> Deserialize<'de, T> for Hinted<H, A> {
#[inline]
fn deserialize_into<'out>(
out: &'out mut Option<T>,
state: &mut State,
) -> SinkHandle<'out, 'de> {
A::deserialize_into(out, state)
}
fn expecting() -> Cow<'static, str> {
A::expecting()
}
fn describe_type(d: &mut dyn Describe) {
A::describe_type(d)
}
#[inline]
fn initial_value() -> Option<T> {
A::initial_value()
}
#[inline]
fn __private_atom_into(
out: &mut Option<T>,
atom: Atom,
state: &mut State,
) -> Result<(), Error> {
A::__private_atom_into(out, atom, state)
}
#[inline]
fn __private_borrowed_atom_into(
out: &mut Option<T>,
atom: Atom<'de>,
state: &mut State,
) -> Result<(), Error> {
A::__private_borrowed_atom_into(out, atom, state)
}
#[inline]
fn __private_is_bytes() -> bool {
A::__private_is_bytes()
}
#[inline]
fn __private_vec_from_bytes(bytes: Vec<u8>) -> Option<Vec<T>> {
A::__private_vec_from_bytes(bytes)
}
#[inline]
fn __private_array_from_bytes<const N: usize>(bytes: &[u8]) -> Option<[T; N]> {
A::__private_array_from_bytes(bytes)
}
#[inline(always)]
fn __private_raw() -> Option<&'static crate::ext::RawFormatInfo> {
A::__private_raw()
}
#[inline]
fn __private_collects() -> bool {
A::__private_collects()
}
#[inline]
fn __private_collect_into<'out>(
out: &'out mut Option<T>,
state: &mut State,
) -> SinkHandle<'out, 'de> {
A::__private_collect_into(out, state)
}
#[inline]
fn __private_collect_update<'out>(
value: &'out mut T,
first: bool,
state: &mut State,
) -> SinkHandle<'out, 'de> {
A::__private_collect_update(value, first, state)
}
#[inline]
fn __private_collect_empty() -> Option<T> {
A::__private_collect_empty()
}
}
pub struct CompactLayout;
impl Hint for CompactLayout {
#[inline]
fn set(state: &mut State) {
Layout::Compact.set(state);
}
}
pub struct ExpandedLayout;
impl Hint for ExpandedLayout {
#[inline]
fn set(state: &mut State) {
Layout::Expanded.set(state);
}
}
pub type Compact<A = Same> = Hinted<CompactLayout, A>;
pub type Expanded<A = Same> = Hinted<ExpandedLayout, A>;