use crate::{ config::Endian, de::read::Reader, error::{DecodeError, IntegerType}, }; pub fn varint_decode_i16(read: &mut R, endian: Endian) -> Result { 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 _ } else { // negative number // !m * 2 + 1 = n // !m * 2 = n - 1 // !m = (n - 1) / 2 // m = !((n - 1) / 2) // since we have n is odd, we have floor(n / 2) = floor((n - 1) / 2) !(n / 2) as _ }) } pub fn varint_decode_i32(read: &mut R, endian: Endian) -> Result { 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 _ } else { // negative number // !m * 2 + 1 = n // !m * 2 = n - 1 // !m = (n - 1) / 2 // m = !((n - 1) / 2) // since we have n is odd, we have floor(n / 2) = floor((n - 1) / 2) !(n / 2) as _ }) } pub fn varint_decode_i64(read: &mut R, endian: Endian) -> Result { 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 _ } else { // negative number // !m * 2 + 1 = n // !m * 2 = n - 1 // !m = (n - 1) / 2 // m = !((n - 1) / 2) // since we have n is odd, we have floor(n / 2) = floor((n - 1) / 2) !(n / 2) as _ }) } pub fn varint_decode_i128(read: &mut R, endian: Endian) -> Result { 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 _ } else { // negative number // !m * 2 + 1 = n // !m * 2 = n - 1 // !m = (n - 1) / 2 // m = !((n - 1) / 2) // since we have n is odd, we have floor(n / 2) = floor((n - 1) / 2) !(n / 2) as _ }) } pub fn varint_decode_isize(read: &mut R, endian: Endian) -> Result { 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), } }