use crate::event::{Atom, Bytes};
use crate::ser::boxed::unsize;
use crate::ser::{Boxed, MapEmitter, SeqEmitter, SerializeHandle, StructEmitter};
use crate::{State, Text};
use alloc::string::String;
pub enum Chunk<'a> {
Atom(Atom<'a>),
Struct(Boxed<dyn StructEmitter + 'a>),
Map(Boxed<dyn MapEmitter + 'a>),
Seq(Boxed<dyn SeqEmitter + 'a>),
Forward(SerializeHandle<'a>),
}
impl<'a> Chunk<'a> {
#[inline(always)]
pub fn seq<E: SeqEmitter + 'a>(emitter: E, state: &mut State) -> Chunk<'a> {
Chunk::Seq(unsize(Boxed::arena(emitter, state), |x| {
x as *mut (dyn SeqEmitter + 'a)
}))
}
#[inline(always)]
pub fn map<E: MapEmitter + 'a>(emitter: E, state: &mut State) -> Chunk<'a> {
Chunk::Map(unsize(Boxed::arena(emitter, state), |x| {
x as *mut (dyn MapEmitter + 'a)
}))
}
#[inline(always)]
pub fn structure<E: StructEmitter + 'a>(emitter: E, state: &mut State) -> Chunk<'a> {
Chunk::Struct(unsize(Boxed::arena(emitter, state), |x| {
x as *mut (dyn StructEmitter + 'a)
}))
}
}
impl<'a> From<Atom<'a>> for Chunk<'a> {
fn from(atom: Atom<'a>) -> Self {
Chunk::Atom(atom)
}
}
macro_rules! impl_from {
($ty:ty, $atom:ident) => {
impl From<$ty> for Chunk<'static> {
fn from(value: $ty) -> Self {
Chunk::Atom(Atom::$atom(value as _))
}
}
};
}
impl_from!(u64, U64);
impl_from!(i64, I64);
impl_from!(usize, U64);
impl_from!(isize, I64);
impl_from!(bool, Bool);
impl_from!(char, Char);
impl From<f64> for Chunk<'static> {
fn from(value: f64) -> Self {
Chunk::Atom(Atom::F64(value))
}
}
impl From<f32> for Chunk<'static> {
fn from(value: f32) -> Self {
Chunk::Atom(Atom::F32(value))
}
}
impl From<()> for Chunk<'static> {
fn from(_: ()) -> Chunk<'static> {
Chunk::Atom(Atom::Null)
}
}
impl<'a> From<&'a str> for Chunk<'a> {
fn from(value: &'a str) -> Chunk<'a> {
Chunk::Atom(Atom::Str(Text::borrowed(value)))
}
}
impl<'a> From<&'a [u8]> for Chunk<'a> {
fn from(value: &'a [u8]) -> Chunk<'a> {
Chunk::Atom(Atom::Bytes(Bytes::borrowed(value)))
}
}
impl From<String> for Chunk<'static> {
fn from(value: String) -> Chunk<'static> {
Chunk::Atom(Atom::Str(Text::owned(value)))
}
}
#[cfg(target_pointer_width = "64")]
const _: () = assert!(core::mem::size_of::<Chunk<'static>>() == 32);
#[cfg(target_pointer_width = "32")]
const _: () = assert!(core::mem::size_of::<Chunk<'static>>() == 24);