diff --git a/src/de/decoder.rs b/src/de/decoder.rs index 2819ec7..309ab69 100644 --- a/src/de/decoder.rs +++ b/src/de/decoder.rs @@ -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 { } } +impl<'a, 'de, R: BorrowReader<'de>, C: Config> BorrowDecode<'de> for &'a mut Decoder { + 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 { fn decode_u8(&mut self) -> Result { let mut bytes = [0u8; 1]; @@ -198,10 +207,6 @@ impl<'a, 'de, R: Reader<'de>, C: Config> Decode<'de> for &'a mut Decoder { }) } - fn decode_slice(&mut self, len: usize) -> Result<&'de [u8], DecodeError> { - self.reader.forward_read(len, |s| s) - } - fn decode_array(&mut self) -> Result<[u8; N], DecodeError> { let mut array = [0u8; N]; self.reader.read(&mut array)?; diff --git a/src/de/impls.rs b/src/de/impls.rs index 9218939..afbb55f 100644 --- a/src/de/impls.rs +++ b/src/de/impls.rs @@ -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>(mut decoder: D) -> Result { +impl<'a, 'de: 'a> BorrowDecodable<'de> for &'a [u8] { + fn borrow_decode>(mut decoder: D) -> Result { let len = usize::decode(&mut decoder)?; decoder.decode_slice(len) } } -impl<'de> Decodable<'de> for &'de str { - fn decode>(decoder: D) -> Result { - let slice: &[u8] = Decodable::decode(decoder)?; +impl<'a, 'de: 'a> BorrowDecodable<'de> for &'a str { + fn borrow_decode>(decoder: D) -> Result { + 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(&mut self) -> Result<[u8; N], DecodeError> { T::decode_array::(self) } diff --git a/src/de/mod.rs b/src/de/mod.rs index 31f3b38..d0dc730 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -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>(decoder: D) -> Result; } +pub trait BorrowDecodable<'de>: Sized { + fn borrow_decode>(decoder: D) -> Result; +} + +impl<'de, T: Decodable<'de>> BorrowDecodable<'de> for T { + fn borrow_decode>(decoder: D) -> Result { + Decodable::decode(decoder) + } +} + pub trait Decode<'de> { fn decode_u8(&mut self) -> Result; fn decode_u16(&mut self) -> Result; @@ -27,6 +37,9 @@ pub trait Decode<'de> { fn decode_f32(&mut self) -> Result; fn decode_f64(&mut self) -> Result; - fn decode_slice(&mut self, len: usize) -> Result<&'de [u8], DecodeError>; fn decode_array(&mut self) -> Result<[u8; N], DecodeError>; } + +pub trait BorrowDecode<'de>: Decode<'de> { + fn decode_slice(&mut self, len: usize) -> Result<&'de [u8], DecodeError>; +} diff --git a/src/de/read.rs b/src/de/read.rs index f78fcf0..a9280e6 100644 --- a/src/de/read.rs +++ b/src/de/read.rs @@ -2,9 +2,10 @@ use crate::error::DecodeError; pub trait Reader<'storage> { fn read(&mut self, bytes: &mut [u8]) -> Result<(), DecodeError>; - fn forward_read(&mut self, length: usize, visitor: F) -> Result - 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(&mut self, length: usize, visitor: F) -> Result - 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), + } } } diff --git a/src/lib.rs b/src/lib.rs index 3857395..debac78 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,17 +43,33 @@ pub fn encode_into_slice_with_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 { 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 { 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 { + 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 { + let mut decoder = de::Decoder::<_, C>::new(src, _config); D::decode(&mut decoder) }