diff --git a/src/de/read.rs b/src/de/read.rs index 2d188bd..eeae2c8 100644 --- a/src/de/read.rs +++ b/src/de/read.rs @@ -75,7 +75,9 @@ impl<'storage> Reader for SliceReader<'storage> { #[inline(always)] fn read(&mut self, bytes: &mut [u8]) -> Result<(), DecodeError> { if bytes.len() > self.slice.len() { - return Err(DecodeError::UnexpectedEnd); + return Err(DecodeError::UnexpectedEnd { + additional: bytes.len() - self.slice.len(), + }); } let (read_slice, remaining) = self.slice.split_at(bytes.len()); bytes.copy_from_slice(read_slice); @@ -99,7 +101,9 @@ impl<'storage> BorrowReader<'storage> for SliceReader<'storage> { #[inline(always)] fn take_bytes(&mut self, length: usize) -> Result<&'storage [u8], DecodeError> { if length > self.slice.len() { - return Err(DecodeError::UnexpectedEnd); + return Err(DecodeError::UnexpectedEnd { + additional: length - self.slice.len(), + }); } let (read_slice, remaining) = self.slice.split_at(length); self.slice = remaining; diff --git a/src/error.rs b/src/error.rs index ac31efd..c5c365f 100644 --- a/src/error.rs +++ b/src/error.rs @@ -68,7 +68,14 @@ impl core::fmt::Display for EncodeError { #[derive(Debug, PartialEq)] pub enum DecodeError { /// The reader reached its end but more bytes were expected. - UnexpectedEnd, + UnexpectedEnd { + /// Gives an estimate of how many extra bytes are needed. + /// + /// **Note**: this is only an estimate and not indicative of the actual bytes needed. + /// + /// **Note**: Bincode has no look-ahead mechanism. This means that this will only return the amount of bytes to be read for the current action, and not take into account the entire data structure being read. + additional: usize, + }, /// The given configuration limit was exceeded LimitExceeded, diff --git a/src/features/impl_std.rs b/src/features/impl_std.rs index ab8ed00..c923001 100644 --- a/src/features/impl_std.rs +++ b/src/features/impl_std.rs @@ -49,7 +49,9 @@ where fn read(&mut self, bytes: &mut [u8]) -> Result<(), DecodeError> { match self.reader.read_exact(bytes) { Ok(_) => Ok(()), - Err(_) => Err(DecodeError::UnexpectedEnd), + Err(_) => Err(DecodeError::UnexpectedEnd { + additional: bytes.len(), + }), } } } @@ -61,7 +63,9 @@ where fn read(&mut self, bytes: &mut [u8]) -> Result<(), DecodeError> { match self.read_exact(bytes) { Ok(_) => Ok(()), - Err(_) => Err(DecodeError::UnexpectedEnd), + Err(_) => Err(DecodeError::UnexpectedEnd { + additional: bytes.len(), + }), } } diff --git a/src/varint/decode_unsigned.rs b/src/varint/decode_unsigned.rs index d5574e0..1d53751 100644 --- a/src/varint/decode_unsigned.rs +++ b/src/varint/decode_unsigned.rs @@ -422,8 +422,8 @@ fn test_decode_u16() { found: IntegerType::U128, }, ), - (&[U16_BYTE], DecodeError::UnexpectedEnd), - (&[U16_BYTE, 0], DecodeError::UnexpectedEnd), + (&[U16_BYTE], DecodeError::UnexpectedEnd { additional: 2 }), + (&[U16_BYTE, 0], DecodeError::UnexpectedEnd { additional: 1 }), ]; for (slice, expected) in errors { @@ -466,12 +466,18 @@ fn test_decode_u32() { found: IntegerType::U128, }, ), - (&[U16_BYTE], DecodeError::UnexpectedEnd), - (&[U16_BYTE, 0], DecodeError::UnexpectedEnd), - (&[U32_BYTE], DecodeError::UnexpectedEnd), - (&[U32_BYTE, 0], DecodeError::UnexpectedEnd), - (&[U32_BYTE, 0, 0], DecodeError::UnexpectedEnd), - (&[U32_BYTE, 0, 0, 0], DecodeError::UnexpectedEnd), + (&[U16_BYTE], DecodeError::UnexpectedEnd { additional: 2 }), + (&[U16_BYTE, 0], DecodeError::UnexpectedEnd { additional: 1 }), + (&[U32_BYTE], DecodeError::UnexpectedEnd { additional: 4 }), + (&[U32_BYTE, 0], DecodeError::UnexpectedEnd { additional: 3 }), + ( + &[U32_BYTE, 0, 0], + DecodeError::UnexpectedEnd { additional: 2 }, + ), + ( + &[U32_BYTE, 0, 0, 0], + DecodeError::UnexpectedEnd { additional: 1 }, + ), ]; for (slice, expected) in errors { @@ -512,20 +518,44 @@ fn test_decode_u64() { found: IntegerType::U128, }, ), - (&[U16_BYTE], DecodeError::UnexpectedEnd), - (&[U16_BYTE, 0], DecodeError::UnexpectedEnd), - (&[U32_BYTE], DecodeError::UnexpectedEnd), - (&[U32_BYTE, 0], DecodeError::UnexpectedEnd), - (&[U32_BYTE, 0, 0], DecodeError::UnexpectedEnd), - (&[U32_BYTE, 0, 0, 0], DecodeError::UnexpectedEnd), - (&[U64_BYTE], DecodeError::UnexpectedEnd), - (&[U64_BYTE, 0], DecodeError::UnexpectedEnd), - (&[U64_BYTE, 0, 0], DecodeError::UnexpectedEnd), - (&[U64_BYTE, 0, 0, 0], DecodeError::UnexpectedEnd), - (&[U64_BYTE, 0, 0, 0, 0], DecodeError::UnexpectedEnd), - (&[U64_BYTE, 0, 0, 0, 0, 0], DecodeError::UnexpectedEnd), - (&[U64_BYTE, 0, 0, 0, 0, 0, 0], DecodeError::UnexpectedEnd), - (&[U64_BYTE, 0, 0, 0, 0, 0, 0, 0], DecodeError::UnexpectedEnd), + (&[U16_BYTE], DecodeError::UnexpectedEnd { additional: 2 }), + (&[U16_BYTE, 0], DecodeError::UnexpectedEnd { additional: 1 }), + (&[U32_BYTE], DecodeError::UnexpectedEnd { additional: 4 }), + (&[U32_BYTE, 0], DecodeError::UnexpectedEnd { additional: 3 }), + ( + &[U32_BYTE, 0, 0], + DecodeError::UnexpectedEnd { additional: 2 }, + ), + ( + &[U32_BYTE, 0, 0, 0], + DecodeError::UnexpectedEnd { additional: 1 }, + ), + (&[U64_BYTE], DecodeError::UnexpectedEnd { additional: 8 }), + (&[U64_BYTE, 0], DecodeError::UnexpectedEnd { additional: 7 }), + ( + &[U64_BYTE, 0, 0], + DecodeError::UnexpectedEnd { additional: 6 }, + ), + ( + &[U64_BYTE, 0, 0, 0], + DecodeError::UnexpectedEnd { additional: 5 }, + ), + ( + &[U64_BYTE, 0, 0, 0, 0], + DecodeError::UnexpectedEnd { additional: 4 }, + ), + ( + &[U64_BYTE, 0, 0, 0, 0, 0], + DecodeError::UnexpectedEnd { additional: 3 }, + ), + ( + &[U64_BYTE, 0, 0, 0, 0, 0, 0], + DecodeError::UnexpectedEnd { additional: 2 }, + ), + ( + &[U64_BYTE, 0, 0, 0, 0, 0, 0, 0], + DecodeError::UnexpectedEnd { additional: 1 }, + ), ]; for (slice, expected) in errors { @@ -564,58 +594,104 @@ fn test_decode_u128() { } let errors: &[(&[u8], DecodeError)] = &[ - (&[U16_BYTE], DecodeError::UnexpectedEnd), - (&[U16_BYTE, 0], DecodeError::UnexpectedEnd), - (&[U32_BYTE], DecodeError::UnexpectedEnd), - (&[U32_BYTE, 0], DecodeError::UnexpectedEnd), - (&[U32_BYTE, 0, 0], DecodeError::UnexpectedEnd), - (&[U32_BYTE, 0, 0, 0], DecodeError::UnexpectedEnd), - (&[U64_BYTE], DecodeError::UnexpectedEnd), - (&[U64_BYTE, 0], DecodeError::UnexpectedEnd), - (&[U64_BYTE, 0, 0], DecodeError::UnexpectedEnd), - (&[U64_BYTE, 0, 0, 0], DecodeError::UnexpectedEnd), - (&[U64_BYTE, 0, 0, 0, 0], DecodeError::UnexpectedEnd), - (&[U64_BYTE, 0, 0, 0, 0, 0], DecodeError::UnexpectedEnd), - (&[U64_BYTE, 0, 0, 0, 0, 0, 0], DecodeError::UnexpectedEnd), - (&[U64_BYTE, 0, 0, 0, 0, 0, 0, 0], DecodeError::UnexpectedEnd), - (&[U128_BYTE], DecodeError::UnexpectedEnd), - (&[U128_BYTE, 0], DecodeError::UnexpectedEnd), - (&[U128_BYTE, 0, 0], DecodeError::UnexpectedEnd), - (&[U128_BYTE, 0, 0, 0], DecodeError::UnexpectedEnd), - (&[U128_BYTE, 0, 0, 0, 0], DecodeError::UnexpectedEnd), - (&[U128_BYTE, 0, 0, 0, 0, 0], DecodeError::UnexpectedEnd), - (&[U128_BYTE, 0, 0, 0, 0, 0, 0], DecodeError::UnexpectedEnd), + (&[U16_BYTE], DecodeError::UnexpectedEnd { additional: 2 }), + (&[U16_BYTE, 0], DecodeError::UnexpectedEnd { additional: 1 }), + (&[U32_BYTE], DecodeError::UnexpectedEnd { additional: 4 }), + (&[U32_BYTE, 0], DecodeError::UnexpectedEnd { additional: 3 }), + ( + &[U32_BYTE, 0, 0], + DecodeError::UnexpectedEnd { additional: 2 }, + ), + ( + &[U32_BYTE, 0, 0, 0], + DecodeError::UnexpectedEnd { additional: 1 }, + ), + (&[U64_BYTE], DecodeError::UnexpectedEnd { additional: 8 }), + (&[U64_BYTE, 0], DecodeError::UnexpectedEnd { additional: 7 }), + ( + &[U64_BYTE, 0, 0], + DecodeError::UnexpectedEnd { additional: 6 }, + ), + ( + &[U64_BYTE, 0, 0, 0], + DecodeError::UnexpectedEnd { additional: 5 }, + ), + ( + &[U64_BYTE, 0, 0, 0, 0], + DecodeError::UnexpectedEnd { additional: 4 }, + ), + ( + &[U64_BYTE, 0, 0, 0, 0, 0], + DecodeError::UnexpectedEnd { additional: 3 }, + ), + ( + &[U64_BYTE, 0, 0, 0, 0, 0, 0], + DecodeError::UnexpectedEnd { additional: 2 }, + ), + ( + &[U64_BYTE, 0, 0, 0, 0, 0, 0, 0], + DecodeError::UnexpectedEnd { additional: 1 }, + ), + (&[U128_BYTE], DecodeError::UnexpectedEnd { additional: 16 }), + ( + &[U128_BYTE, 0], + DecodeError::UnexpectedEnd { additional: 15 }, + ), + ( + &[U128_BYTE, 0, 0], + DecodeError::UnexpectedEnd { additional: 14 }, + ), + ( + &[U128_BYTE, 0, 0, 0], + DecodeError::UnexpectedEnd { additional: 13 }, + ), + ( + &[U128_BYTE, 0, 0, 0, 0], + DecodeError::UnexpectedEnd { additional: 12 }, + ), + ( + &[U128_BYTE, 0, 0, 0, 0, 0], + DecodeError::UnexpectedEnd { additional: 11 }, + ), + ( + &[U128_BYTE, 0, 0, 0, 0, 0, 0], + DecodeError::UnexpectedEnd { additional: 10 }, + ), ( &[U128_BYTE, 0, 0, 0, 0, 0, 0, 0], - DecodeError::UnexpectedEnd, + DecodeError::UnexpectedEnd { additional: 9 }, ), ( &[U128_BYTE, 0, 0, 0, 0, 0, 0, 0, 0], - DecodeError::UnexpectedEnd, + DecodeError::UnexpectedEnd { additional: 8 }, ), ( &[U128_BYTE, 0, 0, 0, 0, 0, 0, 0, 0, 0], - DecodeError::UnexpectedEnd, + DecodeError::UnexpectedEnd { additional: 7 }, ), ( &[U128_BYTE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - DecodeError::UnexpectedEnd, + DecodeError::UnexpectedEnd { additional: 6 }, ), ( &[U128_BYTE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - DecodeError::UnexpectedEnd, + DecodeError::UnexpectedEnd { additional: 5 }, ), ( &[U128_BYTE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - DecodeError::UnexpectedEnd, + DecodeError::UnexpectedEnd { additional: 4 }, ), ( &[U128_BYTE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - DecodeError::UnexpectedEnd, + DecodeError::UnexpectedEnd { additional: 3 }, ), ( &[U128_BYTE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - DecodeError::UnexpectedEnd, + DecodeError::UnexpectedEnd { additional: 2 }, + ), + ( + &[U128_BYTE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + DecodeError::UnexpectedEnd { additional: 1 }, ), ];