Enable non-slice readers

This commit is contained in:
Lena Hellström 2021-09-22 15:08:52 +02:00
parent 9c7fb85e0e
commit 4b672de110
5 changed files with 68 additions and 27 deletions

View File

@ -1,4 +1,7 @@
use super::{read::Reader, Decode}; use super::{
read::{BorrowReader, Reader},
BorrowDecode, Decode,
};
use crate::{ use crate::{
config::{Config, Endian, IntEncoding}, config::{Config, Endian, IntEncoding},
error::DecodeError, error::DecodeError,
@ -23,6 +26,12 @@ impl<'de, R: Reader<'de>, C: Config> Decoder<R, C> {
} }
} }
impl<'a, 'de, R: BorrowReader<'de>, C: Config> BorrowDecode<'de> for &'a mut Decoder<R, C> {
fn decode_slice(&mut self, len: usize) -> Result<&'de [u8], DecodeError> {
self.reader.take_bytes(len)
}
}
impl<'a, 'de, R: Reader<'de>, C: Config> Decode<'de> for &'a mut Decoder<R, C> { impl<'a, 'de, R: Reader<'de>, C: Config> Decode<'de> for &'a mut Decoder<R, C> {
fn decode_u8(&mut self) -> Result<u8, DecodeError> { fn decode_u8(&mut self) -> Result<u8, DecodeError> {
let mut bytes = [0u8; 1]; let mut bytes = [0u8; 1];
@ -198,10 +207,6 @@ impl<'a, 'de, R: Reader<'de>, C: Config> Decode<'de> for &'a mut Decoder<R, C> {
}) })
} }
fn decode_slice(&mut self, len: usize) -> Result<&'de [u8], DecodeError> {
self.reader.forward_read(len, |s| s)
}
fn decode_array<const N: usize>(&mut self) -> Result<[u8; N], DecodeError> { fn decode_array<const N: usize>(&mut self) -> Result<[u8; N], DecodeError> {
let mut array = [0u8; N]; let mut array = [0u8; N];
self.reader.read(&mut array)?; self.reader.read(&mut array)?;

View File

@ -1,4 +1,4 @@
use super::{Decodable, Decode}; use super::{BorrowDecodable, BorrowDecode, Decodable, Decode};
use crate::error::DecodeError; use crate::error::DecodeError;
impl<'de> Decodable<'de> for u8 { impl<'de> Decodable<'de> for u8 {
@ -85,16 +85,16 @@ impl<'de> Decodable<'de> for f64 {
} }
} }
impl<'de> Decodable<'de> for &'de [u8] { impl<'a, 'de: 'a> BorrowDecodable<'de> for &'a [u8] {
fn decode<D: Decode<'de>>(mut decoder: D) -> Result<Self, DecodeError> { fn borrow_decode<D: BorrowDecode<'de>>(mut decoder: D) -> Result<Self, DecodeError> {
let len = usize::decode(&mut decoder)?; let len = usize::decode(&mut decoder)?;
decoder.decode_slice(len) decoder.decode_slice(len)
} }
} }
impl<'de> Decodable<'de> for &'de str { impl<'a, 'de: 'a> BorrowDecodable<'de> for &'a str {
fn decode<D: Decode<'de>>(decoder: D) -> Result<Self, DecodeError> { fn borrow_decode<D: BorrowDecode<'de>>(decoder: D) -> Result<Self, DecodeError> {
let slice: &[u8] = Decodable::decode(decoder)?; let slice: &[u8] = BorrowDecodable::borrow_decode(decoder)?;
core::str::from_utf8(slice).map_err(DecodeError::Utf8) core::str::from_utf8(slice).map_err(DecodeError::Utf8)
} }
} }
@ -171,10 +171,6 @@ where
T::decode_f64(self) T::decode_f64(self)
} }
fn decode_slice(&mut self, len: usize) -> Result<&'de [u8], DecodeError> {
T::decode_slice(self, len)
}
fn decode_array<const N: usize>(&mut self) -> Result<[u8; N], DecodeError> { fn decode_array<const N: usize>(&mut self) -> Result<[u8; N], DecodeError> {
T::decode_array::<N>(self) T::decode_array::<N>(self)
} }

View File

@ -6,10 +6,20 @@ mod impls;
pub mod read; pub mod read;
pub use self::decoder::Decoder; pub use self::decoder::Decoder;
pub trait Decodable<'de>: Sized { pub trait Decodable<'de>: Sized + BorrowDecodable<'de> {
fn decode<D: Decode<'de>>(decoder: D) -> Result<Self, DecodeError>; fn decode<D: Decode<'de>>(decoder: D) -> Result<Self, DecodeError>;
} }
pub trait BorrowDecodable<'de>: Sized {
fn borrow_decode<D: BorrowDecode<'de>>(decoder: D) -> Result<Self, DecodeError>;
}
impl<'de, T: Decodable<'de>> BorrowDecodable<'de> for T {
fn borrow_decode<D: Decode<'de>>(decoder: D) -> Result<Self, DecodeError> {
Decodable::decode(decoder)
}
}
pub trait Decode<'de> { pub trait Decode<'de> {
fn decode_u8(&mut self) -> Result<u8, DecodeError>; fn decode_u8(&mut self) -> Result<u8, DecodeError>;
fn decode_u16(&mut self) -> Result<u16, DecodeError>; fn decode_u16(&mut self) -> Result<u16, DecodeError>;
@ -27,6 +37,9 @@ pub trait Decode<'de> {
fn decode_f32(&mut self) -> Result<f32, DecodeError>; fn decode_f32(&mut self) -> Result<f32, DecodeError>;
fn decode_f64(&mut self) -> Result<f64, DecodeError>; fn decode_f64(&mut self) -> Result<f64, DecodeError>;
fn decode_slice(&mut self, len: usize) -> Result<&'de [u8], DecodeError>;
fn decode_array<const N: usize>(&mut self) -> Result<[u8; N], DecodeError>; fn decode_array<const N: usize>(&mut self) -> Result<[u8; N], DecodeError>;
} }
pub trait BorrowDecode<'de>: Decode<'de> {
fn decode_slice(&mut self, len: usize) -> Result<&'de [u8], DecodeError>;
}

View File

@ -2,9 +2,10 @@ use crate::error::DecodeError;
pub trait Reader<'storage> { pub trait Reader<'storage> {
fn read(&mut self, bytes: &mut [u8]) -> Result<(), DecodeError>; fn read(&mut self, bytes: &mut [u8]) -> Result<(), DecodeError>;
fn forward_read<F, R>(&mut self, length: usize, visitor: F) -> Result<R, DecodeError> }
where
F: Fn(&'storage [u8]) -> R; pub trait BorrowReader<'storage>: Reader<'storage> {
fn take_bytes(&mut self, length: usize) -> Result<&'storage [u8], DecodeError>;
} }
pub struct SliceReader<'storage> { pub struct SliceReader<'storage> {
@ -40,12 +41,22 @@ impl<'storage> Reader<'storage> for SliceReader<'storage> {
Ok(()) Ok(())
} }
}
impl<'storage> BorrowReader<'storage> for SliceReader<'storage> {
#[inline(always)] #[inline(always)]
fn forward_read<F, R>(&mut self, length: usize, visitor: F) -> Result<R, DecodeError> fn take_bytes(&mut self, length: usize) -> Result<&'storage [u8], DecodeError> {
where self.get_byte_slice(length)
F: Fn(&'storage [u8]) -> R, }
{ }
Ok(visitor(self.get_byte_slice(length)?))
#[cfg(feature = "std")]
impl<'storage, R: std::io::Read> Reader<'storage> for R {
#[inline(always)]
fn read(&mut self, bytes: &mut [u8]) -> Result<(), DecodeError> {
match self.read_exact(bytes) {
Ok(_) => Ok(()),
Err(_) => Err(DecodeError::UnexpectedEnd),
}
} }
} }

View File

@ -43,17 +43,33 @@ pub fn encode_into_slice_with_config<E: enc::Encodeable, C: Config>(
Ok(encoder.into_writer().bytes_written()) Ok(encoder.into_writer().bytes_written())
} }
pub fn decode<'__de, D: de::Decodable<'__de>>( pub fn decode<'__de, D: de::BorrowDecodable<'__de>>(
src: &'__de mut [u8], src: &'__de mut [u8],
) -> Result<D, error::DecodeError> { ) -> Result<D, error::DecodeError> {
decode_with_config(src, config::Default) decode_with_config(src, config::Default)
} }
pub fn decode_with_config<'__de, D: de::Decodable<'__de>, C: Config>( pub fn decode_with_config<'__de, D: de::BorrowDecodable<'__de>, C: Config>(
src: &'__de mut [u8], src: &'__de mut [u8],
_config: C, _config: C,
) -> Result<D, error::DecodeError> { ) -> Result<D, error::DecodeError> {
let reader = de::read::SliceReader::new(src); let reader = de::read::SliceReader::new(src);
let mut decoder = de::Decoder::<_, C>::new(reader, _config); let mut decoder = de::Decoder::<_, C>::new(reader, _config);
D::borrow_decode(&mut decoder)
}
#[cfg(feature = "std")]
pub fn decode_from<'__de, D: de::Decodable<'__de>, R: std::io::Read>(
src: &'__de mut R,
) -> Result<D, error::DecodeError> {
decode_from_with_config(src, config::Default)
}
#[cfg(feature = "std")]
pub fn decode_from_with_config<'__de, D: de::Decodable<'__de>, C: Config, R: std::io::Read>(
src: &'__de mut R,
_config: C,
) -> Result<D, error::DecodeError> {
let mut decoder = de::Decoder::<_, C>::new(src, _config);
D::decode(&mut decoder) D::decode(&mut decoder)
} }