use alloc::boxed::Box;
use crate::{
codec_err::DecodeError, nested_de::*, top_de_input::TopDecodeInput, NestedDecodeInput, TypeInfo,
};
pub trait TopDecode: Sized {
#[doc(hidden)]
const TYPE_INFO: TypeInfo = TypeInfo::Unknown;
fn top_decode<I: TopDecodeInput>(input: I) -> Result<Self, DecodeError>;
#[inline]
fn top_decode_or_exit<I: TopDecodeInput, ExitCtx: Clone>(
input: I,
c: ExitCtx,
exit: fn(ExitCtx, DecodeError) -> !,
) -> Self {
match Self::top_decode(input) {
Ok(v) => v,
Err(e) => exit(c, e),
}
}
#[doc(hidden)]
#[inline]
fn top_decode_boxed<I: TopDecodeInput>(input: I) -> Result<Box<Self>, DecodeError> {
Ok(Box::new(Self::top_decode(input)?))
}
#[doc(hidden)]
#[inline]
fn top_decode_boxed_or_exit<I: TopDecodeInput, ExitCtx: Clone>(
input: I,
c: ExitCtx,
exit: fn(ExitCtx, DecodeError) -> !,
) -> Box<Self> {
Box::new(Self::top_decode_or_exit(input, c, exit))
}
}
pub fn top_decode_from_nested<T, I>(input: I) -> Result<T, DecodeError>
where
I: TopDecodeInput,
T: NestedDecode,
{
let mut nested_buffer = input.into_nested_buffer();
let result = T::dep_decode(&mut nested_buffer)?;
if !nested_buffer.is_depleted() {
return Err(DecodeError::INPUT_TOO_LONG);
}
Ok(result)
}
pub fn top_decode_from_nested_or_exit<T, I, ExitCtx: Clone>(
input: I,
c: ExitCtx,
exit: fn(ExitCtx, DecodeError) -> !,
) -> T
where
I: TopDecodeInput,
T: NestedDecode,
{
let mut nested_buffer = input.into_nested_buffer();
let result = T::dep_decode_or_exit(&mut nested_buffer, c.clone(), exit);
if !nested_buffer.is_depleted() {
exit(c, DecodeError::INPUT_TOO_LONG);
}
result
}