use crate::{reader::Reader, Error, Result};
#[cfg(feature = "alloc")]
use alloc::{string::String, vec::Vec};
#[cfg(feature = "bytes")]
use bytes::Bytes;
#[cfg(feature = "pem")]
use {crate::PEM_LINE_WIDTH, pem::PemLabel};
const MAX_SIZE: usize = 0xFFFFF;
pub trait Decode: Sized {
type Error: From<Error>;
fn decode(reader: &mut impl Reader) -> core::result::Result<Self, Self::Error>;
}
#[cfg(feature = "pem")]
pub trait DecodePem: Decode + PemLabel + Sized {
fn decode_pem(pem: impl AsRef<[u8]>) -> core::result::Result<Self, Self::Error>;
}
#[cfg(feature = "pem")]
impl<T: Decode + PemLabel + Sized> DecodePem for T {
fn decode_pem(pem: impl AsRef<[u8]>) -> core::result::Result<Self, Self::Error> {
let mut reader =
pem::Decoder::new_wrapped(pem.as_ref(), PEM_LINE_WIDTH).map_err(Error::from)?;
Self::validate_pem_label(reader.type_label()).map_err(Error::from)?;
let ret = Self::decode(&mut reader)?;
Ok(reader.finish(ret)?)
}
}
impl Decode for u8 {
type Error = Error;
fn decode(reader: &mut impl Reader) -> Result<Self> {
let mut buf = [0];
reader.read(&mut buf)?;
Ok(buf[0])
}
}
impl Decode for u32 {
type Error = Error;
fn decode(reader: &mut impl Reader) -> Result<Self> {
let mut bytes = [0u8; 4];
reader.read(&mut bytes)?;
Ok(u32::from_be_bytes(bytes))
}
}
impl Decode for u64 {
type Error = Error;
fn decode(reader: &mut impl Reader) -> Result<Self> {
let mut bytes = [0u8; 8];
reader.read(&mut bytes)?;
Ok(u64::from_be_bytes(bytes))
}
}
impl Decode for usize {
type Error = Error;
fn decode(reader: &mut impl Reader) -> Result<Self> {
let n = usize::try_from(u32::decode(reader)?)?;
if n <= MAX_SIZE {
Ok(n)
} else {
Err(Error::Overflow)
}
}
}
impl<const N: usize> Decode for [u8; N] {
type Error = Error;
fn decode(reader: &mut impl Reader) -> Result<Self> {
reader.read_prefixed(|reader| {
let mut result = [(); N].map(|_| 0);
reader.read(&mut result)?;
Ok(result)
})
}
}
#[cfg(feature = "alloc")]
impl Decode for Vec<u8> {
type Error = Error;
fn decode(reader: &mut impl Reader) -> Result<Self> {
reader.read_prefixed(|reader| {
let mut result = vec![0u8; reader.remaining_len()];
reader.read(&mut result)?;
Ok(result)
})
}
}
#[cfg(feature = "alloc")]
impl Decode for String {
type Error = Error;
fn decode(reader: &mut impl Reader) -> Result<Self> {
String::from_utf8(Vec::decode(reader)?).map_err(|_| Error::CharacterEncoding)
}
}
#[cfg(feature = "alloc")]
impl Decode for Vec<String> {
type Error = Error;
fn decode(reader: &mut impl Reader) -> Result<Self> {
reader.read_prefixed(|reader| {
let mut entries = Self::new();
while !reader.is_finished() {
entries.push(String::decode(reader)?);
}
Ok(entries)
})
}
}
#[cfg(feature = "bytes")]
impl Decode for Bytes {
type Error = Error;
fn decode(reader: &mut impl Reader) -> Result<Self> {
Vec::<u8>::decode(reader).map(Into::into)
}
}