Made the varint decode_signed module report the correct errors

This commit is contained in:
Victor Koenders 2021-10-17 17:21:34 +02:00
parent 02a9b2cb71
commit 2fd2a8d8e2
2 changed files with 57 additions and 6 deletions

View File

@ -105,6 +105,23 @@ pub enum DecodeError {
},
}
impl DecodeError {
/// If the current error is `InvalidIntegerType`, change the `expected` and
/// `found` values from `Ux` to `Ix`. This is needed to have correct error
/// reporting in src/varint/decode_signed.rs since this calls
/// src/varint/decode_unsigned.rs and needs to correct the `expected` and
/// `found` types.
pub(crate) fn change_integer_type_to_signed(self) -> DecodeError {
match self {
Self::InvalidIntegerType { expected, found } => Self::InvalidIntegerType {
expected: expected.into_signed(),
found: found.into_signed(),
},
other => other,
}
}
}
/// Integer types. Used by [DecodeError]. These types have no purpose other than being shown in errors.
#[non_exhaustive]
#[derive(Debug)]
@ -124,3 +141,20 @@ pub enum IntegerType {
I128,
Isize,
}
impl IntegerType {
/// Change the `Ux` value to the associated `Ix` value.
/// Returns the old value if `self` is already `Ix`.
pub(crate) fn into_signed(self) -> Self {
match self {
Self::U8 => Self::I8,
Self::U16 => Self::I16,
Self::U32 => Self::I32,
Self::U64 => Self::I64,
Self::U128 => Self::I128,
Self::Usize => Self::Isize,
other => other,
}
}
}

View File

@ -1,7 +1,12 @@
use crate::{config::Endian, de::read::Reader, error::DecodeError};
use crate::{
config::Endian,
de::read::Reader,
error::{DecodeError, IntegerType},
};
pub fn varint_decode_i16<R: Reader>(read: &mut R, endian: Endian) -> Result<i16, DecodeError> {
let n = super::varint_decode_u16(read, endian)?;
let n = super::varint_decode_u16(read, endian)
.map_err(DecodeError::change_integer_type_to_signed)?;
Ok(if n % 2 == 0 {
// positive number
(n / 2) as _
@ -17,7 +22,8 @@ pub fn varint_decode_i16<R: Reader>(read: &mut R, endian: Endian) -> Result<i16,
}
pub fn varint_decode_i32<R: Reader>(read: &mut R, endian: Endian) -> Result<i32, DecodeError> {
let n = super::varint_decode_u32(read, endian)?;
let n = super::varint_decode_u32(read, endian)
.map_err(DecodeError::change_integer_type_to_signed)?;
Ok(if n % 2 == 0 {
// positive number
(n / 2) as _
@ -33,7 +39,8 @@ pub fn varint_decode_i32<R: Reader>(read: &mut R, endian: Endian) -> Result<i32,
}
pub fn varint_decode_i64<R: Reader>(read: &mut R, endian: Endian) -> Result<i64, DecodeError> {
let n = super::varint_decode_u64(read, endian)?;
let n = super::varint_decode_u64(read, endian)
.map_err(DecodeError::change_integer_type_to_signed)?;
Ok(if n % 2 == 0 {
// positive number
(n / 2) as _
@ -49,7 +56,8 @@ pub fn varint_decode_i64<R: Reader>(read: &mut R, endian: Endian) -> Result<i64,
}
pub fn varint_decode_i128<R: Reader>(read: &mut R, endian: Endian) -> Result<i128, DecodeError> {
let n = super::varint_decode_u128(read, endian)?;
let n = super::varint_decode_u128(read, endian)
.map_err(DecodeError::change_integer_type_to_signed)?;
Ok(if n % 2 == 0 {
// positive number
(n / 2) as _
@ -65,5 +73,14 @@ pub fn varint_decode_i128<R: Reader>(read: &mut R, endian: Endian) -> Result<i12
}
pub fn varint_decode_isize<R: Reader>(read: &mut R, endian: Endian) -> Result<isize, DecodeError> {
varint_decode_i64(read, endian).map(|v| v as isize)
match varint_decode_i64(read, endian) {
Ok(val) => Ok(val as isize),
Err(DecodeError::InvalidIntegerType { found, .. }) => {
Err(DecodeError::InvalidIntegerType {
expected: IntegerType::Isize,
found: found.into_signed(),
})
}
Err(e) => Err(e),
}
}