diff --git a/src/de/decoder.rs b/src/de/decoder.rs index ff10d37..4991963 100644 --- a/src/de/decoder.rs +++ b/src/de/decoder.rs @@ -1,215 +1,234 @@ -use super::{ - read::{BorrowReader, Reader}, - BorrowDecode, Decode, -}; -use crate::{ - config::{Config, Endian, IntEncoding}, - error::DecodeError, -}; -use core::marker::PhantomData; - -pub struct Decoder { - reader: R, - config: PhantomData, -} - -impl<'de, R: Reader<'de>, C: Config> Decoder { - pub fn new(reader: R, _config: C) -> Decoder { - Decoder { - reader, - config: PhantomData, - } - } - - pub fn into_reader(self) -> R { - self.reader - } -} - -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 for &'a mut Decoder { - fn decode_u8(&mut self) -> Result { - let mut bytes = [0u8; 1]; - self.reader.read(&mut bytes)?; - Ok(bytes[0]) - } - - fn decode_u16(&mut self) -> Result { - match C::INT_ENCODING { - IntEncoding::Variable => crate::varint::varint_decode_u16(&mut self.reader, C::ENDIAN), - IntEncoding::Fixed => { - let mut bytes = [0u8; 2]; - self.reader.read(&mut bytes)?; - Ok(match C::ENDIAN { - Endian::Little => u16::from_le_bytes(bytes), - Endian::Big => u16::from_be_bytes(bytes), - }) - } - } - } - - fn decode_u32(&mut self) -> Result { - match C::INT_ENCODING { - IntEncoding::Variable => crate::varint::varint_decode_u32(&mut self.reader, C::ENDIAN), - IntEncoding::Fixed => { - let mut bytes = [0u8; 4]; - self.reader.read(&mut bytes)?; - Ok(match C::ENDIAN { - Endian::Little => u32::from_le_bytes(bytes), - Endian::Big => u32::from_be_bytes(bytes), - }) - } - } - } - - fn decode_u64(&mut self) -> Result { - match C::INT_ENCODING { - IntEncoding::Variable => crate::varint::varint_decode_u64(&mut self.reader, C::ENDIAN), - IntEncoding::Fixed => { - let mut bytes = [0u8; 8]; - self.reader.read(&mut bytes)?; - Ok(match C::ENDIAN { - Endian::Little => u64::from_le_bytes(bytes), - Endian::Big => u64::from_be_bytes(bytes), - }) - } - } - } - - fn decode_u128(&mut self) -> Result { - match C::INT_ENCODING { - IntEncoding::Variable => crate::varint::varint_decode_u128(&mut self.reader, C::ENDIAN), - IntEncoding::Fixed => { - let mut bytes = [0u8; 16]; - self.reader.read(&mut bytes)?; - Ok(match C::ENDIAN { - Endian::Little => u128::from_le_bytes(bytes), - Endian::Big => u128::from_be_bytes(bytes), - }) - } - } - } - - fn decode_usize(&mut self) -> Result { - match C::INT_ENCODING { - IntEncoding::Variable => { - crate::varint::varint_decode_usize(&mut self.reader, C::ENDIAN) - } - IntEncoding::Fixed => { - let mut bytes = [0u8; 8]; - self.reader.read(&mut bytes)?; - Ok(match C::ENDIAN { - Endian::Little => u64::from_le_bytes(bytes), - Endian::Big => u64::from_be_bytes(bytes), - } as usize) - } - } - } - - fn decode_i8(&mut self) -> Result { - let mut bytes = [0u8; 1]; - self.reader.read(&mut bytes)?; - Ok(bytes[0] as i8) - } - - fn decode_i16(&mut self) -> Result { - match C::INT_ENCODING { - IntEncoding::Variable => crate::varint::varint_decode_i16(&mut self.reader, C::ENDIAN), - IntEncoding::Fixed => { - let mut bytes = [0u8; 2]; - self.reader.read(&mut bytes)?; - Ok(match C::ENDIAN { - Endian::Little => i16::from_le_bytes(bytes), - Endian::Big => i16::from_be_bytes(bytes), - }) - } - } - } - - fn decode_i32(&mut self) -> Result { - match C::INT_ENCODING { - IntEncoding::Variable => crate::varint::varint_decode_i32(&mut self.reader, C::ENDIAN), - IntEncoding::Fixed => { - let mut bytes = [0u8; 4]; - self.reader.read(&mut bytes)?; - Ok(match C::ENDIAN { - Endian::Little => i32::from_le_bytes(bytes), - Endian::Big => i32::from_be_bytes(bytes), - }) - } - } - } - - fn decode_i64(&mut self) -> Result { - match C::INT_ENCODING { - IntEncoding::Variable => crate::varint::varint_decode_i64(&mut self.reader, C::ENDIAN), - IntEncoding::Fixed => { - let mut bytes = [0u8; 8]; - self.reader.read(&mut bytes)?; - Ok(match C::ENDIAN { - Endian::Little => i64::from_le_bytes(bytes), - Endian::Big => i64::from_be_bytes(bytes), - }) - } - } - } - - fn decode_i128(&mut self) -> Result { - match C::INT_ENCODING { - IntEncoding::Variable => crate::varint::varint_decode_i128(&mut self.reader, C::ENDIAN), - IntEncoding::Fixed => { - let mut bytes = [0u8; 16]; - self.reader.read(&mut bytes)?; - Ok(match C::ENDIAN { - Endian::Little => i128::from_le_bytes(bytes), - Endian::Big => i128::from_be_bytes(bytes), - }) - } - } - } - - fn decode_isize(&mut self) -> Result { - match C::INT_ENCODING { - IntEncoding::Variable => { - crate::varint::varint_decode_isize(&mut self.reader, C::ENDIAN) - } - IntEncoding::Fixed => { - let mut bytes = [0u8; 8]; - self.reader.read(&mut bytes)?; - Ok(match C::ENDIAN { - Endian::Little => i64::from_le_bytes(bytes), - Endian::Big => i64::from_be_bytes(bytes), - } as isize) - } - } - } - - fn decode_f32(&mut self) -> Result { - let mut bytes = [0u8; 4]; - self.reader.read(&mut bytes)?; - Ok(match C::ENDIAN { - Endian::Little => f32::from_le_bytes(bytes), - Endian::Big => f32::from_be_bytes(bytes), - }) - } - - fn decode_f64(&mut self) -> Result { - let mut bytes = [0u8; 8]; - self.reader.read(&mut bytes)?; - Ok(match C::ENDIAN { - Endian::Little => f64::from_le_bytes(bytes), - Endian::Big => f64::from_be_bytes(bytes), - }) - } - - fn decode_array(&mut self) -> Result<[u8; N], DecodeError> { - let mut array = [0u8; N]; - self.reader.read(&mut array)?; - Ok(array) - } -} +use super::{ + read::{BorrowReader, Reader}, + BorrowDecode, Decode, +}; +use crate::{ + config::{Config, Endian, IntEncoding}, + error::DecodeError, +}; +use core::marker::PhantomData; + +/// A Decoder that reads bytes from a given reader `R`. +/// +/// This struct should rarely be used. +/// In most cases, prefer any of the `decode` functions. +/// +/// The ByteOrder that is chosen will impact the endianness that +/// is used to read integers out of the reader. +/// +/// ``` +/// # let slice: &[u8] = &[0, 0, 0, 0]; +/// # let some_reader = bincode::de::read::SliceReader::new(slice); +/// use bincode::de::{Decoder, Decodable}; +/// use bincode::config; +/// let mut decoder = Decoder::new(some_reader, config::Default); +/// // this u32 can be any Decodable +/// let value = u32::decode(&mut decoder).unwrap(); +/// ``` +pub struct Decoder { + reader: R, + config: PhantomData, +} + +impl<'de, R: Reader<'de>, C: Config> Decoder { + /// Construct a new Decoder + pub fn new(reader: R, _config: C) -> Decoder { + Decoder { + reader, + config: PhantomData, + } + } + + /// Consume the decoder and return the inner reader + pub fn into_reader(self) -> R { + self.reader + } +} + +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 for &'a mut Decoder { + fn decode_u8(&mut self) -> Result { + let mut bytes = [0u8; 1]; + self.reader.read(&mut bytes)?; + Ok(bytes[0]) + } + + fn decode_u16(&mut self) -> Result { + match C::INT_ENCODING { + IntEncoding::Variable => crate::varint::varint_decode_u16(&mut self.reader, C::ENDIAN), + IntEncoding::Fixed => { + let mut bytes = [0u8; 2]; + self.reader.read(&mut bytes)?; + Ok(match C::ENDIAN { + Endian::Little => u16::from_le_bytes(bytes), + Endian::Big => u16::from_be_bytes(bytes), + }) + } + } + } + + fn decode_u32(&mut self) -> Result { + match C::INT_ENCODING { + IntEncoding::Variable => crate::varint::varint_decode_u32(&mut self.reader, C::ENDIAN), + IntEncoding::Fixed => { + let mut bytes = [0u8; 4]; + self.reader.read(&mut bytes)?; + Ok(match C::ENDIAN { + Endian::Little => u32::from_le_bytes(bytes), + Endian::Big => u32::from_be_bytes(bytes), + }) + } + } + } + + fn decode_u64(&mut self) -> Result { + match C::INT_ENCODING { + IntEncoding::Variable => crate::varint::varint_decode_u64(&mut self.reader, C::ENDIAN), + IntEncoding::Fixed => { + let mut bytes = [0u8; 8]; + self.reader.read(&mut bytes)?; + Ok(match C::ENDIAN { + Endian::Little => u64::from_le_bytes(bytes), + Endian::Big => u64::from_be_bytes(bytes), + }) + } + } + } + + fn decode_u128(&mut self) -> Result { + match C::INT_ENCODING { + IntEncoding::Variable => crate::varint::varint_decode_u128(&mut self.reader, C::ENDIAN), + IntEncoding::Fixed => { + let mut bytes = [0u8; 16]; + self.reader.read(&mut bytes)?; + Ok(match C::ENDIAN { + Endian::Little => u128::from_le_bytes(bytes), + Endian::Big => u128::from_be_bytes(bytes), + }) + } + } + } + + fn decode_usize(&mut self) -> Result { + match C::INT_ENCODING { + IntEncoding::Variable => { + crate::varint::varint_decode_usize(&mut self.reader, C::ENDIAN) + } + IntEncoding::Fixed => { + let mut bytes = [0u8; 8]; + self.reader.read(&mut bytes)?; + Ok(match C::ENDIAN { + Endian::Little => u64::from_le_bytes(bytes), + Endian::Big => u64::from_be_bytes(bytes), + } as usize) + } + } + } + + fn decode_i8(&mut self) -> Result { + let mut bytes = [0u8; 1]; + self.reader.read(&mut bytes)?; + Ok(bytes[0] as i8) + } + + fn decode_i16(&mut self) -> Result { + match C::INT_ENCODING { + IntEncoding::Variable => crate::varint::varint_decode_i16(&mut self.reader, C::ENDIAN), + IntEncoding::Fixed => { + let mut bytes = [0u8; 2]; + self.reader.read(&mut bytes)?; + Ok(match C::ENDIAN { + Endian::Little => i16::from_le_bytes(bytes), + Endian::Big => i16::from_be_bytes(bytes), + }) + } + } + } + + fn decode_i32(&mut self) -> Result { + match C::INT_ENCODING { + IntEncoding::Variable => crate::varint::varint_decode_i32(&mut self.reader, C::ENDIAN), + IntEncoding::Fixed => { + let mut bytes = [0u8; 4]; + self.reader.read(&mut bytes)?; + Ok(match C::ENDIAN { + Endian::Little => i32::from_le_bytes(bytes), + Endian::Big => i32::from_be_bytes(bytes), + }) + } + } + } + + fn decode_i64(&mut self) -> Result { + match C::INT_ENCODING { + IntEncoding::Variable => crate::varint::varint_decode_i64(&mut self.reader, C::ENDIAN), + IntEncoding::Fixed => { + let mut bytes = [0u8; 8]; + self.reader.read(&mut bytes)?; + Ok(match C::ENDIAN { + Endian::Little => i64::from_le_bytes(bytes), + Endian::Big => i64::from_be_bytes(bytes), + }) + } + } + } + + fn decode_i128(&mut self) -> Result { + match C::INT_ENCODING { + IntEncoding::Variable => crate::varint::varint_decode_i128(&mut self.reader, C::ENDIAN), + IntEncoding::Fixed => { + let mut bytes = [0u8; 16]; + self.reader.read(&mut bytes)?; + Ok(match C::ENDIAN { + Endian::Little => i128::from_le_bytes(bytes), + Endian::Big => i128::from_be_bytes(bytes), + }) + } + } + } + + fn decode_isize(&mut self) -> Result { + match C::INT_ENCODING { + IntEncoding::Variable => { + crate::varint::varint_decode_isize(&mut self.reader, C::ENDIAN) + } + IntEncoding::Fixed => { + let mut bytes = [0u8; 8]; + self.reader.read(&mut bytes)?; + Ok(match C::ENDIAN { + Endian::Little => i64::from_le_bytes(bytes), + Endian::Big => i64::from_be_bytes(bytes), + } as isize) + } + } + } + + fn decode_f32(&mut self) -> Result { + let mut bytes = [0u8; 4]; + self.reader.read(&mut bytes)?; + Ok(match C::ENDIAN { + Endian::Little => f32::from_le_bytes(bytes), + Endian::Big => f32::from_be_bytes(bytes), + }) + } + + fn decode_f64(&mut self) -> Result { + let mut bytes = [0u8; 8]; + self.reader.read(&mut bytes)?; + Ok(match C::ENDIAN { + Endian::Little => f64::from_le_bytes(bytes), + Endian::Big => f64::from_be_bytes(bytes), + }) + } + + fn decode_array(&mut self) -> Result<[u8; N], DecodeError> { + let mut array = [0u8; N]; + self.reader.read(&mut array)?; + Ok(array) + } +} diff --git a/src/de/mod.rs b/src/de/mod.rs index 71ef281..eed91f3 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -1,45 +1,75 @@ -use crate::error::DecodeError; - -mod decoder; -mod impls; - -pub mod read; -pub use self::decoder::Decoder; - -pub trait Decodable: for<'de> BorrowDecodable<'de> { - fn decode(decoder: D) -> Result; -} - -pub trait BorrowDecodable<'de>: Sized { - fn borrow_decode>(decoder: D) -> Result; -} - -impl<'de, T: Decodable> BorrowDecodable<'de> for T { - fn borrow_decode(decoder: D) -> Result { - Decodable::decode(decoder) - } -} - -pub trait Decode { - fn decode_u8(&mut self) -> Result; - fn decode_u16(&mut self) -> Result; - fn decode_u32(&mut self) -> Result; - fn decode_u64(&mut self) -> Result; - fn decode_u128(&mut self) -> Result; - fn decode_usize(&mut self) -> Result; - - fn decode_i8(&mut self) -> Result; - fn decode_i16(&mut self) -> Result; - fn decode_i32(&mut self) -> Result; - fn decode_i64(&mut self) -> Result; - fn decode_i128(&mut self) -> Result; - fn decode_isize(&mut self) -> Result; - - fn decode_f32(&mut self) -> Result; - fn decode_f64(&mut self) -> Result; - fn decode_array(&mut self) -> Result<[u8; N], DecodeError>; -} - -pub trait BorrowDecode<'de>: Decode { - fn decode_slice(&mut self, len: usize) -> Result<&'de [u8], DecodeError>; -} +use crate::error::DecodeError; + +mod decoder; +mod impls; + +pub mod read; +pub use self::decoder::Decoder; + +/// Trait that makes a type able to be decoded, akin to serde's `DeserializeOwned` trait. +/// +/// This trait should be implemented for types which do not have references to data in the reader. For types that contain e.g. `&str` and `&[u8]`, implement [BorrowDecodable] instead. +/// +/// Whenever you implement `Decodable` for your type, the base trait `BorrowDecodable` is automatically implemented. +pub trait Decodable: for<'de> BorrowDecodable<'de> { + /// Attempt to decode this type with the given [Decode]. + fn decode(decoder: D) -> Result; +} + +/// Trait that makes a type able to be decoded, akin to serde's `Deserialize` trait. +/// +/// This trait should be implemented for types that contain borrowed data, like `&str` and `&[u8]`. If your type does not have borrowed data, consider implementing [Decodable] instead. +pub trait BorrowDecodable<'de>: Sized { + /// Attempt to decode this type with the given [BorrowDecode]. + fn borrow_decode>(decoder: D) -> Result; +} + +impl<'de, T: Decodable> BorrowDecodable<'de> for T { + fn borrow_decode(decoder: D) -> Result { + Decodable::decode(decoder) + } +} + +/// Any source that can decode basic types. This type is most notably implemented for [Decoder]. +pub trait Decode { + /// Attempt to decode a `u8` + fn decode_u8(&mut self) -> Result; + /// Attempt to decode a `u16` + fn decode_u16(&mut self) -> Result; + /// Attempt to decode a `u32` + fn decode_u32(&mut self) -> Result; + /// Attempt to decode a `u64` + fn decode_u64(&mut self) -> Result; + /// Attempt to decode a `u128` + fn decode_u128(&mut self) -> Result; + /// Attempt to decode a `usize` + fn decode_usize(&mut self) -> Result; + + /// Attempt to decode a `i8` + fn decode_i8(&mut self) -> Result; + /// Attempt to decode a `i16` + fn decode_i16(&mut self) -> Result; + /// Attempt to decode a `i32` + fn decode_i32(&mut self) -> Result; + /// Attempt to decode a `i64` + fn decode_i64(&mut self) -> Result; + /// Attempt to decode a `i128` + fn decode_i128(&mut self) -> Result; + /// Attempt to decode a `isize` + fn decode_isize(&mut self) -> Result; + + /// Attempt to decode a `f32` + fn decode_f32(&mut self) -> Result; + /// Attempt to decode a `f64` + fn decode_f64(&mut self) -> Result; + /// Attempt to decode an array of `N` entries. + fn decode_array(&mut self) -> Result<[u8; N], DecodeError>; +} + +/// Any source that can decode basic types. This type is most notably implemented for [Decoder]. +/// +/// This is an extension of [Decode] that can also return borrowed data. +pub trait BorrowDecode<'de>: Decode { + /// Decode `len` bytes, returning the slice as borrowed data. + fn decode_slice(&mut self, len: usize) -> Result<&'de [u8], DecodeError>; +} diff --git a/src/de/read.rs b/src/de/read.rs index 2b568da..6a0030a 100644 --- a/src/de/read.rs +++ b/src/de/read.rs @@ -1,20 +1,40 @@ +//! This module contains reader-based structs and traits. +//! +//! Because `std::io::Read` is only limited to `std` and not `core`, we provide 2 alternative readers. +//! +//! [Reader] is a reader for sources that do not own their data. It is assumed that the reader's data is dropped after the `read` method is called. This reader is incapable of reading borrowed data, like `&str` and `&[u8]`. +//! +//! [BorrowReader] is an extension of `Reader` that also allows returning borrowed data. A `BorrowReader` allows reading `&str` and `&[u8]`. +//! +//! Specifically the `Reader` trait is used by [Decodable] and the `BorrowReader` trait is used by `[BorrowDecodable]`. +//! +//! [Decodable]: ../trait.Decodable.html +//! [BorrowDecodable]: ../trait.BorrowDecodable.html + use crate::error::DecodeError; +/// A reader for owned data. See the module documentation for more information. pub trait Reader<'storage> { + /// Fill the given `bytes` argument with values. Exactly the length of the given slice must be filled, or else an error must be returned. fn read(&mut self, bytes: &mut [u8]) -> Result<(), DecodeError>; } +/// A reader for borrowed data. Implementors of this must also implement the [Reader] trait. See the module documentation for more information. pub trait BorrowReader<'storage>: Reader<'storage> { + /// Read exactly `length` bytes and return a slice to this data. If not enough bytes could be read, an error should be returned. + /// + /// *note*: Exactly `length` bytes must be returned. If less bytes are returned, bincode may panic. If more bytes are returned, the excess bytes may be discarded. fn take_bytes(&mut self, length: usize) -> Result<&'storage [u8], DecodeError>; } +/// A reader type for `&[u8]` slices. Implements both [Reader] and [BorrowReader], and thus can be used for borrowed data. pub struct SliceReader<'storage> { slice: &'storage [u8], } impl<'storage> SliceReader<'storage> { /// Constructs a slice reader - pub(crate) fn new(bytes: &'storage [u8]) -> SliceReader<'storage> { + pub fn new(bytes: &'storage [u8]) -> SliceReader<'storage> { SliceReader { slice: bytes } }