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::{
config::{Config, Endian, IntEncoding},
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> {
fn decode_u8(&mut self) -> Result<u8, DecodeError> {
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> {
let mut array = [0u8; N];
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;
impl<'de> Decodable<'de> for u8 {
@ -85,16 +85,16 @@ impl<'de> Decodable<'de> for f64 {
}
}
impl<'de> Decodable<'de> for &'de [u8] {
fn decode<D: Decode<'de>>(mut decoder: D) -> Result<Self, DecodeError> {
impl<'a, 'de: 'a> BorrowDecodable<'de> for &'a [u8] {
fn borrow_decode<D: BorrowDecode<'de>>(mut decoder: D) -> Result<Self, DecodeError> {
let len = usize::decode(&mut decoder)?;
decoder.decode_slice(len)
}
}
impl<'de> Decodable<'de> for &'de str {
fn decode<D: Decode<'de>>(decoder: D) -> Result<Self, DecodeError> {
let slice: &[u8] = Decodable::decode(decoder)?;
impl<'a, 'de: 'a> BorrowDecodable<'de> for &'a str {
fn borrow_decode<D: BorrowDecode<'de>>(decoder: D) -> Result<Self, DecodeError> {
let slice: &[u8] = BorrowDecodable::borrow_decode(decoder)?;
core::str::from_utf8(slice).map_err(DecodeError::Utf8)
}
}
@ -171,10 +171,6 @@ where
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> {
T::decode_array::<N>(self)
}

View File

@ -6,10 +6,20 @@ mod impls;
pub mod read;
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>;
}
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> {
fn decode_u8(&mut self) -> Result<u8, 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_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>;
}
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> {
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> {
@ -40,12 +41,22 @@ impl<'storage> Reader<'storage> for SliceReader<'storage> {
Ok(())
}
}
impl<'storage> BorrowReader<'storage> for SliceReader<'storage> {
#[inline(always)]
fn forward_read<F, R>(&mut self, length: usize, visitor: F) -> Result<R, DecodeError>
where
F: Fn(&'storage [u8]) -> R,
{
Ok(visitor(self.get_byte_slice(length)?))
fn take_bytes(&mut self, length: usize) -> Result<&'storage [u8], DecodeError> {
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())
}
pub fn decode<'__de, D: de::Decodable<'__de>>(
pub fn decode<'__de, D: de::BorrowDecodable<'__de>>(
src: &'__de mut [u8],
) -> Result<D, error::DecodeError> {
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],
_config: C,
) -> Result<D, error::DecodeError> {
let reader = de::read::SliceReader::new(src);
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)
}