#[cfg(feature = "alloc")]
use core::option::Option;
use crate::BoolCodec;
pub struct RemainingCodec;
impl RemainingCodec {
pub const fn new() -> Self {
RemainingCodec
}
}
impl<'encoded, 'decoded> crate::Decoder<'encoded, 'decoded> for RemainingCodec
where
'encoded: 'decoded,
{
type Decoded = &'decoded [u8];
fn decode(
&self,
encoded: &'encoded [u8],
offset: &mut usize,
) -> Result<Self::Decoded, crate::error::DecodeError> {
if *offset > encoded.len() {
return Err(crate::error::DecodeError::InvalidData);
}
let remaining = &encoded[*offset..];
*offset = encoded.len();
Ok(remaining)
}
}
impl crate::Encoder for RemainingCodec {
type Decoded = [u8];
fn encode(
&self,
decoded: &Self::Decoded,
encoded: &mut [u8],
offset: &mut usize,
) -> Result<(), crate::error::EncodeError> {
let end = *offset + decoded.len();
if end > encoded.len() {
return Err(crate::error::EncodeError::BufferTooSmall);
}
encoded[*offset..end].copy_from_slice(decoded);
*offset = end;
Ok(())
}
}
impl crate::Measurer for RemainingCodec {
type Decoded = [u8];
fn measure(&self, decoded: &Self::Decoded) -> Result<usize, crate::error::EncodeError> {
Ok(decoded.len())
}
}
pub struct OptionCodec<Item>(Item);
impl<Item> OptionCodec<Item> {
pub fn new(item: Item) -> Self {
Self(item)
}
}
impl<'encoded, 'decoded, Item> crate::Decoder<'encoded, 'decoded> for OptionCodec<Item>
where
Item: crate::Decoder<'encoded, 'decoded>,
{
type Decoded = Option<Item::Decoded>;
fn decode(
&self,
encoded: &'encoded [u8],
offset: &mut usize,
) -> Result<Self::Decoded, crate::error::DecodeError> {
let flag = BoolCodec.decode(encoded, offset)?;
if flag {
Ok(Option::None)
} else {
let item = self.0.decode(encoded, offset)?;
Ok(Option::Some(item))
}
}
}
impl<Item> crate::Encoder for OptionCodec<Item>
where
Item: crate::Encoder,
Item::Decoded: Sized,
{
type Decoded = Option<Item::Decoded>;
fn encode(
&self,
decoded: &Self::Decoded,
encoded: &mut [u8],
offset: &mut usize,
) -> Result<(), crate::error::EncodeError> {
match decoded {
Option::None => {
BoolCodec.encode(&true, encoded, offset)?;
Ok(())
}
Option::Some(item) => {
BoolCodec.encode(&false, encoded, offset)?;
self.0.encode(item, encoded, offset)
}
}
}
}
impl<Item> crate::Measurer for OptionCodec<Item>
where
Item: crate::Measurer,
Item::Decoded: Sized,
{
type Decoded = Option<Item::Decoded>;
fn measure(&self, decoded: &Self::Decoded) -> Result<usize, crate::error::EncodeError> {
Ok(match decoded {
Option::None => BoolCodec.measure(&true)?,
Option::Some(item) => BoolCodec.measure(&false)? + self.0.measure(item)?,
})
}
}
pub struct BytesCodec<Length>(Length);
impl<Length> BytesCodec<Length> {
pub const fn new(length: Length) -> Self {
Self(length)
}
}
impl<'encoded, 'decoded, 'length, Length> crate::Decoder<'encoded, 'decoded> for BytesCodec<Length>
where
Length: crate::Decoder<'encoded, 'length>,
Length::Decoded: TryInto<usize>,
<Length::Decoded as TryInto<usize>>::Error: Into<crate::error::DecodeError>,
'encoded: 'decoded,
{
type Decoded = &'decoded [u8];
fn decode(
&self,
encoded: &'encoded [u8],
offset: &mut usize,
) -> Result<Self::Decoded, crate::error::DecodeError> {
let size = self
.0
.decode(encoded, offset)?
.try_into()
.map_err(Into::into)?;
if *offset + size > encoded.len() {
return Err(crate::error::DecodeError::InvalidData);
}
let buffer = &encoded[*offset..*offset + size];
*offset += size;
Ok(buffer)
}
}
impl<Length> crate::Encoder for BytesCodec<Length>
where
Length: crate::Encoder,
Length::Decoded: TryFrom<usize>,
<Length::Decoded as TryFrom<usize>>::Error: Into<crate::error::EncodeError>,
{
type Decoded = [u8];
fn encode(
&self,
decoded: &Self::Decoded,
encoded: &mut [u8],
offset: &mut usize,
) -> Result<(), crate::error::EncodeError> {
let size = decoded.len();
self.0
.encode(&size.try_into().map_err(Into::into)?, encoded, offset)?;
let end = *offset + size;
if end > encoded.len() {
return Err(crate::error::EncodeError::BufferTooSmall);
}
encoded[*offset..end].copy_from_slice(decoded);
*offset = end;
Ok(())
}
}
impl<Length> crate::Measurer for BytesCodec<Length>
where
Length: crate::Measurer,
Length::Decoded: TryFrom<usize>,
<Length::Decoded as TryFrom<usize>>::Error: Into<crate::error::EncodeError>,
{
type Decoded = [u8];
fn measure(&self, decoded: &Self::Decoded) -> Result<usize, crate::error::EncodeError> {
let size = decoded.len();
let size_measure = self.0.measure(&size.try_into().map_err(Into::into)?)?;
Ok(size_measure + size)
}
}