use crate::{Format, io::IoRead};
mod array;
pub use array::ArrayDecoder;
mod bin;
pub use bin::BinDecoder;
#[cfg(feature = "alloc")]
pub use bin::BinOwnedDecoder;
pub use bin::DecodeBytes;
pub use bin::ReferenceDecoder;
mod bool;
mod float;
mod int;
mod map;
pub use map::MapDecoder;
mod nil;
pub use nil::NilDecoder;
mod str;
pub use str::{ReferenceStr, ReferenceStrBinDecoder, ReferenceStrDecoder};
mod any;
pub use any::Any;
#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
pub enum Error<E> {
InvalidData,
UnexpectedFormat,
UnexpectedEof,
Io(E),
}
impl<E> core::fmt::Display for Error<E>
where
E: core::fmt::Display,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Error::InvalidData => write!(f, "Cannot decode invalid data"),
Error::UnexpectedFormat => write!(f, "Unexpected format found"),
Error::UnexpectedEof => write!(f, "Unexpected end of data"),
Error::Io(e) => e.fmt(f),
}
}
}
impl<E> core::error::Error for Error<E>
where
E: core::error::Error + 'static,
{
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
match self {
Error::Io(e) => Some(e),
_ => None,
}
}
}
pub trait Decode<'de> {
type Value<'a>: Sized
where
Self: 'a,
'de: 'a;
fn decode<'a, R>(reader: &'a mut R) -> Result<Self::Value<'a>, Error<R::Error>>
where
R: IoRead<'de>,
'de: 'a,
{
let format = <Format as DecodeBorrowed<'de>>::decode_borrowed(reader)?;
Self::decode_with_format(format, reader)
}
fn decode_with_format<'a, R>(
format: Format,
reader: &'a mut R,
) -> Result<Self::Value<'a>, Error<R::Error>>
where
R: IoRead<'de>,
'de: 'a;
}
pub trait DecodeBorrowed<'de> {
type Value;
fn decode_borrowed<R>(
reader: &mut R,
) -> Result<<Self as DecodeBorrowed<'de>>::Value, Error<R::Error>>
where
R: IoRead<'de>,
{
let format = <Format as DecodeBorrowed<'de>>::decode_borrowed(reader)?;
Self::decode_borrowed_with_format(format, reader)
}
fn decode_borrowed_with_format<R>(
format: Format,
reader: &mut R,
) -> Result<<Self as DecodeBorrowed<'de>>::Value, Error<R::Error>>
where
R: IoRead<'de>;
}
pub trait DecodeOwned: for<'de> DecodeBorrowed<'de, Value = Self> {}
impl<T> DecodeOwned for T where T: for<'de> DecodeBorrowed<'de, Value = Self> {}
impl<'de, T> Decode<'de> for T
where
T: DecodeBorrowed<'de>,
T: 'de,
{
type Value<'a>
= <T as DecodeBorrowed<'de>>::Value
where
Self: 'a,
'de: 'a;
fn decode_with_format<'a, R>(
format: Format,
reader: &'a mut R,
) -> Result<Self::Value<'a>, Error<R::Error>>
where
R: IoRead<'de>,
'de: 'a,
{
<T as DecodeBorrowed<'de>>::decode_borrowed_with_format(format, reader)
}
}
impl<'de> DecodeBorrowed<'de> for Format {
type Value = Self;
fn decode_borrowed<R>(reader: &mut R) -> Result<Self::Value, Error<R::Error>>
where
R: IoRead<'de>,
{
let b = reader.read_slice(1).map_err(Error::Io)?;
let byte: [u8; 1] = b.as_bytes().try_into().map_err(|_| Error::UnexpectedEof)?;
Ok(Self::from_byte(byte[0]))
}
fn decode_borrowed_with_format<R>(
format: Format,
_reader: &mut R,
) -> Result<Self::Value, Error<R::Error>>
where
R: IoRead<'de>,
{
Ok(format)
}
}
pub struct NbyteReader<const NBYTE: usize>;
macro_rules! impl_read {
($ty:ty) => {
pub fn read<'de, R>(reader: &mut R) -> core::result::Result<usize, Error<R::Error>>
where
R: IoRead<'de>,
{
const SIZE: usize = core::mem::size_of::<$ty>();
let bytes = reader.read_slice(SIZE).map_err(Error::Io)?;
let slice = bytes.as_bytes();
let data: [u8; SIZE] = slice.try_into().map_err(|_| Error::UnexpectedEof)?;
let val =
usize::try_from(<$ty>::from_be_bytes(data)).map_err(|_| Error::InvalidData)?;
Ok(val)
}
};
}
impl NbyteReader<1> {
impl_read! {u8}
}
impl NbyteReader<2> {
impl_read! {u16}
}
impl NbyteReader<4> {
impl_read! {u32}
}