use alloc::boxed::Box;
use core::fmt;
use core::marker::PhantomData;
use crate::State;
use crate::error::Error;
use crate::event::ContainerShape;
use crate::ser::boxed::{self, Boxed};
use crate::ser::{Begin, Describe, Emit, PlainSink, Serialize};
#[repr(transparent)]
pub(crate) struct Adapted<A, T: ?Sized> {
_marker: PhantomData<fn() -> A>,
value: T,
}
impl<A, T: ?Sized> Adapted<A, T> {
#[inline(always)]
pub(crate) fn new(value: &T) -> &Adapted<A, T> {
unsafe { &*(value as *const T as *const Adapted<A, T>) }
}
#[inline(always)]
pub(crate) fn ptr(value: &T) -> *const Adapted<A, T> {
value as *const T as *const Adapted<A, T>
}
#[inline(always)]
pub(crate) fn get(&self) -> &T {
&self.value
}
}
impl<A, T> Adapted<A, T> {
#[inline(always)]
fn owned(value: T) -> Adapted<A, T> {
Adapted {
_marker: PhantomData,
value,
}
}
}
pub(crate) trait Erased: Sync {
fn erased_serialize(&self, state: &mut State) -> Result<Emit<'_>, Error>;
fn erased_finish(&self, state: &mut State) -> Result<(), Error>;
fn erased_is_optional(&self) -> bool;
fn erased_container_shape(&self) -> ContainerShape;
fn erased_describe(&self, d: &mut dyn Describe);
fn erased_begin(&self, state: &mut State) -> Result<Begin<'_>, Error>;
fn erased_is_plain_value(&self) -> bool;
fn erased_emit_plain(&self, sink: &mut dyn PlainSink) -> Result<(), Error>;
fn erased_plain_cost(&self, budget: usize) -> Option<usize>;
}
impl<A: Serialize<T>, T: ?Sized + Sync> Erased for Adapted<A, T> {
fn erased_serialize(&self, state: &mut State) -> Result<Emit<'_>, Error> {
A::serialize(&self.value, state)
}
fn erased_finish(&self, state: &mut State) -> Result<(), Error> {
A::finish(&self.value, state)
}
fn erased_is_optional(&self) -> bool {
A::is_optional(&self.value)
}
fn erased_container_shape(&self) -> ContainerShape {
A::container_shape(&self.value)
}
fn erased_describe(&self, d: &mut dyn Describe) {
A::describe(&self.value, d)
}
fn erased_begin(&self, state: &mut State) -> Result<Begin<'_>, Error> {
A::__private_begin(&self.value, state)
}
fn erased_is_plain_value(&self) -> bool {
A::__private_is_plain_value(&self.value)
}
fn erased_emit_plain(&self, sink: &mut dyn PlainSink) -> Result<(), Error> {
A::__private_emit_plain(&self.value, sink)
}
fn erased_plain_cost(&self, budget: usize) -> Option<usize> {
A::__private_plain_cost(&self.value, budget)
}
}
#[inline(always)]
pub(crate) unsafe fn erase_unbounded<'a, S: Erased>(value: *const S) -> &'a (dyn Erased + 'a) {
let value: *const (dyn Erased + '_) = value;
unsafe { &*core::mem::transmute::<*const (dyn Erased + '_), *const (dyn Erased + 'a)>(value) }
}
#[derive(Clone, Copy)]
pub struct SerializeRef<'a> {
value: &'a (dyn Erased + 'a),
}
impl<'a> SerializeRef<'a> {
#[inline(always)]
pub fn new<T: Serialize>(value: &'a T) -> SerializeRef<'a> {
SerializeRef {
value: Adapted::<T, T>::new(value),
}
}
#[inline(always)]
pub fn serialize_as<A: Serialize<T>, T: Sync>(value: &'a T) -> SerializeRef<'a> {
SerializeRef {
value: unsafe { erase_unbounded(Adapted::<A, T>::ptr(value)) },
}
}
#[inline(always)]
pub(crate) fn from_dyn(value: &'a (dyn Erased + 'a)) -> SerializeRef<'a> {
SerializeRef { value }
}
#[inline(always)]
pub(crate) fn as_dyn(self) -> &'a (dyn Erased + 'a) {
self.value
}
#[inline]
pub fn serialize(self, state: &mut State) -> Result<Emit<'a>, Error> {
self.value.erased_serialize(state)
}
#[inline]
pub fn finish(self, state: &mut State) -> Result<(), Error> {
self.value.erased_finish(state)
}
#[inline]
pub fn is_optional(self) -> bool {
self.value.erased_is_optional()
}
#[inline]
pub fn container_shape(self) -> ContainerShape {
self.value.erased_container_shape()
}
pub fn describe(self, d: &mut dyn Describe) {
self.value.erased_describe(d)
}
#[inline]
pub(crate) fn begin(self, state: &mut State) -> Result<Begin<'a>, Error> {
self.value.erased_begin(state)
}
#[inline]
pub(crate) fn is_plain_value(self) -> bool {
self.value.erased_is_plain_value()
}
#[inline]
pub(crate) fn emit_plain(self, sink: &mut dyn PlainSink) -> Result<(), Error> {
self.value.erased_emit_plain(sink)
}
#[inline]
pub(crate) fn plain_cost(self, budget: usize) -> Option<usize> {
self.value.erased_plain_cost(budget)
}
}
impl fmt::Debug for SerializeRef<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SerializeRef").finish_non_exhaustive()
}
}
impl<'a, T: Serialize> From<&'a T> for SerializeRef<'a> {
#[inline(always)]
fn from(value: &'a T) -> SerializeRef<'a> {
SerializeRef::new(value)
}
}
impl Serialize for SerializeRef<'_> {
#[inline]
fn serialize<'b>(value: &'b Self, state: &mut State) -> Result<Emit<'b>, Error> {
value.serialize(state)
}
#[inline]
fn finish(value: &Self, state: &mut State) -> Result<(), Error> {
(*value).finish(state)
}
#[inline]
fn is_optional(value: &Self) -> bool {
(*value).is_optional()
}
#[inline]
fn container_shape(value: &Self) -> ContainerShape {
(*value).container_shape()
}
fn describe(value: &Self, d: &mut dyn Describe) {
(*value).describe(d)
}
#[inline]
fn __private_begin<'b>(value: &'b Self, state: &mut State) -> Result<Begin<'b>, Error> {
value.begin(state)
}
#[inline]
fn __private_is_plain_value(value: &Self) -> bool {
value.is_plain_value()
}
#[inline]
fn __private_emit_plain(value: &Self, sink: &mut dyn PlainSink) -> Result<(), Error> {
value.emit_plain(sink)
}
#[inline]
fn __private_plain_cost(value: &Self, budget: usize) -> Option<usize> {
value.plain_cost(budget)
}
}
pub struct SerializeHandle<'a>(pub(crate) HandleInner<'a>);
pub(crate) enum HandleInner<'a> {
Borrowed(SerializeRef<'a>),
Owned(Boxed<dyn Erased + Send + 'a>),
}
impl<'a> SerializeHandle<'a> {
#[inline(always)]
pub fn to<S: Serialize>(value: &'a S) -> SerializeHandle<'a> {
SerializeHandle(HandleInner::Borrowed(SerializeRef::new(value)))
}
#[inline(always)]
pub fn arena<S: Serialize + Send + 'a>(value: S, state: &mut State) -> SerializeHandle<'a> {
SerializeHandle(HandleInner::Owned(boxed::unsize(
Boxed::arena(Adapted::<S, S>::owned(value), state),
|x| x as *mut (dyn Erased + Send + 'a),
)))
}
pub fn heap<S: Serialize + Send + 'a>(value: S) -> SerializeHandle<'a> {
SerializeHandle(HandleInner::Owned(Boxed::from(
Box::new(Adapted::<S, S>::owned(value)) as Box<dyn Erased + Send + 'a>,
)))
}
#[inline(always)]
pub fn get(&self) -> SerializeRef<'_> {
match self.0 {
HandleInner::Borrowed(value) => value,
HandleInner::Owned(ref value) => SerializeRef::from_dyn(&**value),
}
}
}
impl<'a> From<SerializeRef<'a>> for SerializeHandle<'a> {
#[inline(always)]
fn from(value: SerializeRef<'a>) -> SerializeHandle<'a> {
SerializeHandle(HandleInner::Borrowed(value))
}
}
impl fmt::Debug for SerializeHandle<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SerializeHandle").finish_non_exhaustive()
}
}
impl Serialize for SerializeHandle<'_> {
#[inline]
fn serialize<'b>(value: &'b Self, state: &mut State) -> Result<Emit<'b>, Error> {
value.get().serialize(state)
}
#[inline]
fn finish(value: &Self, state: &mut State) -> Result<(), Error> {
value.get().finish(state)
}
#[inline]
fn is_optional(value: &Self) -> bool {
value.get().is_optional()
}
#[inline]
fn container_shape(value: &Self) -> ContainerShape {
value.get().container_shape()
}
fn describe(value: &Self, d: &mut dyn Describe) {
value.get().describe(d)
}
#[inline]
fn __private_begin<'b>(value: &'b Self, state: &mut State) -> Result<Begin<'b>, Error> {
value.get().begin(state)
}
#[inline]
fn __private_is_plain_value(value: &Self) -> bool {
value.get().is_plain_value()
}
#[inline]
fn __private_emit_plain(value: &Self, sink: &mut dyn PlainSink) -> Result<(), Error> {
value.get().emit_plain(sink)
}
#[inline]
fn __private_plain_cost(value: &Self, budget: usize) -> Option<usize> {
value.get().plain_cost(budget)
}
}