Skip to content

Commit

Permalink
Support i128 and u128
Browse files Browse the repository at this point in the history
  • Loading branch information
e00E committed Apr 30, 2020
1 parent 92c1d5d commit 9772ef4
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 21 deletions.
16 changes: 16 additions & 0 deletions src/de/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
AnyNum::U32(x) => visitor.visit_u32(x),
AnyNum::I64(x) => visitor.visit_i64(x),
AnyNum::U64(x) => visitor.visit_u64(x),
AnyNum::I128(x) => visitor.visit_i128(x),
AnyNum::U128(x) => visitor.visit_u128(x),
}
}
b'.' => self.deserialize_f64(visitor),
Expand Down Expand Up @@ -216,6 +218,13 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
visitor.visit_i64(self.bytes.signed_integer()?)
}

fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_i128(self.bytes.signed_integer()?)
}

fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
Expand Down Expand Up @@ -244,6 +253,13 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
visitor.visit_u64(self.bytes.unsigned_integer()?)
}

fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_u128(self.bytes.unsigned_integer()?)
}

fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
Expand Down
14 changes: 14 additions & 0 deletions src/de/tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ impl<'a, 'b: 'a, 'c> de::Deserializer<'b> for &'c mut TagDeserializer<'a, 'b> {
self.d.deserialize_i64(visitor)
}

fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'b>,
{
self.d.deserialize_i128(visitor)
}

fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'b>,
Expand Down Expand Up @@ -99,6 +106,13 @@ impl<'a, 'b: 'a, 'c> de::Deserializer<'b> for &'c mut TagDeserializer<'a, 'b> {
self.d.deserialize_u64(visitor)
}

fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'b>,
{
self.d.deserialize_u128(visitor)
}

fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'b>,
Expand Down
14 changes: 14 additions & 0 deletions src/de/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,27 @@ impl<'de> Visitor<'de> for ValueVisitor {
}

fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: Error,
{
self.visit_i128(v as i128)
}

fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
where
E: Error,
{
self.visit_f64(v as f64)
}

fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: Error,
{
self.visit_u128(v as u128)
}

fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
where
E: Error,
{
Expand Down
39 changes: 24 additions & 15 deletions src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ pub enum AnyNum {
U32(u32),
I64(i64),
U64(u64),
I128(i128),
U128(u128),
}

#[derive(Clone, Copy, Debug)]
Expand Down Expand Up @@ -177,28 +179,33 @@ impl<'a> Bytes<'a> {

any_float(f)
} else {
let max_u8 = std::u8::MAX as u64;
let max_u16 = std::u16::MAX as u64;
let max_u32 = std::u32::MAX as u64;

let min_i8 = std::i8::MIN as i64;
let max_i8 = std::i8::MAX as i64;
let min_i16 = std::i16::MIN as i64;
let max_i16 = std::i16::MAX as i64;
let min_i32 = std::i32::MIN as i64;
let max_i32 = std::i32::MAX as i64;
let max_u8 = std::u8::MAX as u128;
let max_u16 = std::u16::MAX as u128;
let max_u32 = std::u32::MAX as u128;
let max_u64 = std::u64::MAX as u128;

let min_i8 = std::i8::MIN as i128;
let max_i8 = std::i8::MAX as i128;
let min_i16 = std::i16::MIN as i128;
let max_i16 = std::i16::MAX as i128;
let min_i32 = std::i32::MIN as i128;
let max_i32 = std::i32::MAX as i128;
let min_i64 = std::i64::MIN as i128;
let max_i64 = std::i64::MAX as i128;

if is_signed {
match self.signed_integer::<i64>() {
match self.signed_integer::<i128>() {
Ok(x) => {
if x >= min_i8 && x <= max_i8 {
Ok(AnyNum::I8(x as i8))
} else if x >= min_i16 && x <= max_i16 {
Ok(AnyNum::I16(x as i16))
} else if x >= min_i32 && x <= max_i32 {
Ok(AnyNum::I32(x as i32))
} else if x >= min_i64 && x <= max_i64 {
Ok(AnyNum::I64(x as i64))
} else {
Ok(AnyNum::I64(x))
Ok(AnyNum::I128(x))
}
}
Err(_) => {
Expand All @@ -208,16 +215,18 @@ impl<'a> Bytes<'a> {
}
}
} else {
match self.unsigned_integer::<u64>() {
match self.unsigned_integer::<u128>() {
Ok(x) => {
if x <= max_u8 {
Ok(AnyNum::U8(x as u8))
} else if x <= max_u16 {
Ok(AnyNum::U16(x as u16))
} else if x <= max_u32 {
Ok(AnyNum::U32(x as u32))
} else if x <= max_u64 {
Ok(AnyNum::U64(x as u64))
} else {
Ok(AnyNum::U64(x))
Ok(AnyNum::U128(x))
}
}
Err(_) => {
Expand Down Expand Up @@ -828,7 +837,7 @@ macro_rules! impl_num {
};
}

impl_num!(u8 u16 u32 u64 i8 i16 i32 i64);
impl_num!(u8 u16 u32 u64 u128 i8 i16 i32 i64 i128);

#[derive(Clone, Debug)]
pub enum ParsedStr<'a> {
Expand Down
20 changes: 14 additions & 6 deletions src/ser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,36 +338,44 @@ impl<'a> ser::Serializer for &'a mut Serializer {
}

fn serialize_i8(self, v: i8) -> Result<()> {
self.serialize_i64(v as i64)
self.serialize_i128(v as i128)
}

fn serialize_i16(self, v: i16) -> Result<()> {
self.serialize_i64(v as i64)
self.serialize_i128(v as i128)
}

fn serialize_i32(self, v: i32) -> Result<()> {
self.serialize_i64(v as i64)
self.serialize_i128(v as i128)
}

fn serialize_i64(self, v: i64) -> Result<()> {
self.serialize_i128(v as i128)
}

fn serialize_i128(self, v: i128) -> Result<()> {
// TODO optimize
self.output += &v.to_string();
Ok(())
}

fn serialize_u8(self, v: u8) -> Result<()> {
self.serialize_u64(v as u64)
self.serialize_u128(v as u128)
}

fn serialize_u16(self, v: u16) -> Result<()> {
self.serialize_u64(v as u64)
self.serialize_u128(v as u128)
}

fn serialize_u32(self, v: u32) -> Result<()> {
self.serialize_u64(v as u64)
self.serialize_u128(v as u128)
}

fn serialize_u64(self, v: u64) -> Result<()> {
self.serialize_u128(v as u128)
}

fn serialize_u128(self, v: u128) -> Result<()> {
self.output += &v.to_string();
Ok(())
}
Expand Down
32 changes: 32 additions & 0 deletions tests/min_max.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,35 @@ fn test_i64_max() {
from_str(&to_string(&std::i64::MAX).unwrap()).unwrap()
);
}

#[test]
fn test_i128_min() {
assert_eq!(
std::i128::MIN,
from_str(&to_string(&std::i128::MIN).unwrap()).unwrap()
);
}

#[test]
fn test_i128_max() {
assert_eq!(
std::i128::MAX,
from_str(&to_string(&std::i128::MAX).unwrap()).unwrap()
);
}

#[test]
fn test_u128_min() {
assert_eq!(
std::u128::MIN,
from_str(&to_string(&std::u128::MIN).unwrap()).unwrap()
);
}

#[test]
fn test_u128_max() {
assert_eq!(
std::u128::MAX,
from_str(&to_string(&std::u128::MAX).unwrap()).unwrap()
);
}

0 comments on commit 9772ef4

Please sign in to comment.