mod r#as;
mod parser;
pub use self::{r#as::*, parser::*};
use std::{borrow::Cow, mem, rc::Rc, sync::Arc};
use crate::{Cell, Context, FromInto, Same, bits::de::BitReaderExt, either::Either};
pub trait CellDeserialize<'de>: Sized {
type Args;
fn parse(parser: &mut CellParser<'de>, args: Self::Args) -> Result<Self, CellParserError<'de>>;
}
pub trait CellDeserializeOwned: for<'de> CellDeserialize<'de> {}
impl<T> CellDeserializeOwned for T where T: for<'de> CellDeserialize<'de> {}
impl<'de> CellDeserialize<'de> for () {
type Args = ();
#[inline]
fn parse(_parser: &mut CellParser<'de>, _: Self::Args) -> Result<Self, CellParserError<'de>> {
Ok(())
}
}
impl<'de, T, const N: usize> CellDeserialize<'de> for [T; N]
where
T: CellDeserialize<'de>,
T::Args: Clone,
{
type Args = T::Args;
fn parse(parser: &mut CellParser<'de>, args: Self::Args) -> Result<Self, CellParserError<'de>> {
array_util::try_from_fn(|i| {
T::parse(parser, args.clone()).with_context(|| format!("[{i}]"))
})
}
}
macro_rules! impl_cell_deserialize_for_tuple {
($($n:tt:$t:ident),+) => {
impl<'de, $($t),+> CellDeserialize<'de> for ($($t,)+)
where $(
$t: CellDeserialize<'de>,
)+
{
type Args = ($($t::Args,)+);
#[inline]
fn parse(parser: &mut CellParser<'de>, args: Self::Args) -> Result<Self, CellParserError<'de>>
{
Ok(($(
$t::parse(parser, args.$n).context(concat!(".", stringify!($n)))?,
)+))
}
}
};
}
impl_cell_deserialize_for_tuple!(0:T0);
impl_cell_deserialize_for_tuple!(0:T0,1:T1);
impl_cell_deserialize_for_tuple!(0:T0,1:T1,2:T2);
impl_cell_deserialize_for_tuple!(0:T0,1:T1,2:T2,3:T3);
impl_cell_deserialize_for_tuple!(0:T0,1:T1,2:T2,3:T3,4:T4);
impl_cell_deserialize_for_tuple!(0:T0,1:T1,2:T2,3:T3,4:T4,5:T5);
impl_cell_deserialize_for_tuple!(0:T0,1:T1,2:T2,3:T3,4:T4,5:T5,6:T6);
impl_cell_deserialize_for_tuple!(0:T0,1:T1,2:T2,3:T3,4:T4,5:T5,6:T6,7:T7);
impl_cell_deserialize_for_tuple!(0:T0,1:T1,2:T2,3:T3,4:T4,5:T5,6:T6,7:T7,8:T8);
impl_cell_deserialize_for_tuple!(0:T0,1:T1,2:T2,3:T3,4:T4,5:T5,6:T6,7:T7,8:T8,9:T9);
impl<'de, T> CellDeserialize<'de> for Box<T>
where
T: CellDeserialize<'de>,
{
type Args = T::Args;
#[inline]
fn parse(parser: &mut CellParser<'de>, args: Self::Args) -> Result<Self, CellParserError<'de>> {
parser.parse_as::<_, FromInto<T>>(args)
}
}
impl<'de, T> CellDeserialize<'de> for Rc<T>
where
T: CellDeserialize<'de>,
{
type Args = T::Args;
#[inline]
fn parse(parser: &mut CellParser<'de>, args: Self::Args) -> Result<Self, CellParserError<'de>> {
parser.parse_as::<_, FromInto<T>>(args)
}
}
impl<'de, T> CellDeserialize<'de> for Arc<T>
where
T: CellDeserialize<'de>,
{
type Args = T::Args;
#[inline]
fn parse(parser: &mut CellParser<'de>, args: Self::Args) -> Result<Self, CellParserError<'de>> {
parser.parse_as::<_, FromInto<T>>(args)
}
}
impl<'de, 'a, T> CellDeserialize<'de> for Cow<'a, T>
where
T: ToOwned + ?Sized,
T::Owned: CellDeserialize<'de>,
{
type Args = <T::Owned as CellDeserialize<'de>>::Args;
#[inline]
fn parse(parser: &mut CellParser<'de>, args: Self::Args) -> Result<Self, CellParserError<'de>> {
parser.parse::<T::Owned>(args).map(Self::Owned)
}
}
impl<'de, Left, Right> CellDeserialize<'de> for Either<Left, Right>
where
Left: CellDeserialize<'de>,
Right: CellDeserialize<'de>,
{
type Args = (Left::Args, Right::Args);
#[inline]
fn parse(
parser: &mut CellParser<'de>,
(la, ra): Self::Args,
) -> Result<Self, CellParserError<'de>> {
match parser.unpack(()).context("tag")? {
false => parser.parse(la).map(Either::Left).context("left"),
true => parser.parse(ra).map(Either::Right).context("right"),
}
}
}
impl<'de, T> CellDeserialize<'de> for Option<T>
where
T: CellDeserialize<'de>,
{
type Args = T::Args;
#[inline]
fn parse(parser: &mut CellParser<'de>, args: Self::Args) -> Result<Self, CellParserError<'de>> {
parser.parse_as::<_, Either<(), Same>>(args)
}
}
impl<'de> CellDeserialize<'de> for Cell {
type Args = ();
#[inline]
fn parse(parser: &mut CellParser<'de>, _: Self::Args) -> Result<Self, CellParserError<'de>> {
Ok(Self {
is_exotic: parser.is_exotic,
data: mem::take(&mut parser.data).to_bitvec(),
references: mem::take(&mut parser.references).to_vec(),
})
}
}