diff --git a/src/de/id.rs b/src/de/id.rs index d7e242c8..b8d7d59f 100644 --- a/src/de/id.rs +++ b/src/de/id.rs @@ -71,6 +71,13 @@ impl<'a, 'b: 'a, 'c> de::Deserializer<'b> for &'c mut IdDeserializer<'a, 'b> { unimplemented!("IdDeserializer may only be used for identifiers") } + fn deserialize_i128(self, _: V) -> Result + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + fn deserialize_u8(self, _: V) -> Result where V: Visitor<'b>, @@ -99,6 +106,13 @@ impl<'a, 'b: 'a, 'c> de::Deserializer<'b> for &'c mut IdDeserializer<'a, 'b> { unimplemented!("IdDeserializer may only be used for identifiers") } + fn deserialize_u128(self, _: V) -> Result + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + fn deserialize_f32(self, _: V) -> Result where V: Visitor<'b>, diff --git a/src/de/mod.rs b/src/de/mod.rs index 0cad6fb5..34080eef 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -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), @@ -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(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_i128(self.bytes.signed_integer()?) + } + fn deserialize_u8(self, visitor: V) -> Result where V: Visitor<'de>, @@ -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(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_u128(self.bytes.unsigned_integer()?) + } + fn deserialize_f32(self, visitor: V) -> Result where V: Visitor<'de>, diff --git a/src/de/tag.rs b/src/de/tag.rs index 08086671..76a8bb79 100644 --- a/src/de/tag.rs +++ b/src/de/tag.rs @@ -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(self, visitor: V) -> Result + where + V: Visitor<'b>, + { + self.d.deserialize_i128(visitor) + } + fn deserialize_u8(self, visitor: V) -> Result where V: Visitor<'b>, @@ -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(self, visitor: V) -> Result + where + V: Visitor<'b>, + { + self.d.deserialize_u128(visitor) + } + fn deserialize_f32(self, visitor: V) -> Result where V: Visitor<'b>, diff --git a/src/de/value.rs b/src/de/value.rs index da4c6176..e49fad9a 100644 --- a/src/de/value.rs +++ b/src/de/value.rs @@ -50,6 +50,13 @@ impl<'de> Visitor<'de> for ValueVisitor { } fn visit_i64(self, v: i64) -> Result + where + E: Error, + { + self.visit_i128(v as i128) + } + + fn visit_i128(self, v: i128) -> Result where E: Error, { @@ -57,6 +64,13 @@ impl<'de> Visitor<'de> for ValueVisitor { } fn visit_u64(self, v: u64) -> Result + where + E: Error, + { + self.visit_u128(v as u128) + } + + fn visit_u128(self, v: u128) -> Result where E: Error, { diff --git a/src/parse.rs b/src/parse.rs index 309ec82e..95948364 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -25,6 +25,8 @@ pub enum AnyNum { U32(u32), I64(i64), U64(u64), + I128(i128), + U128(u128), } #[derive(Clone, Copy, Debug)] @@ -177,19 +179,22 @@ 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::() { + match self.signed_integer::() { Ok(x) => { if x >= min_i8 && x <= max_i8 { Ok(AnyNum::I8(x as i8)) @@ -197,8 +202,10 @@ impl<'a> Bytes<'a> { 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(_) => { @@ -208,7 +215,7 @@ impl<'a> Bytes<'a> { } } } else { - match self.unsigned_integer::() { + match self.unsigned_integer::() { Ok(x) => { if x <= max_u8 { Ok(AnyNum::U8(x as u8)) @@ -216,8 +223,10 @@ impl<'a> Bytes<'a> { 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(_) => { @@ -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> { diff --git a/src/ser/mod.rs b/src/ser/mod.rs index f0403a10..3bddba57 100644 --- a/src/ser/mod.rs +++ b/src/ser/mod.rs @@ -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(()) } diff --git a/tests/min_max.rs b/tests/min_max.rs index d878a950..f53bcb2c 100644 --- a/tests/min_max.rs +++ b/tests/min_max.rs @@ -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() + ); +} diff --git a/tests/struct_integers.rs b/tests/struct_integers.rs new file mode 100644 index 00000000..67cc0dfb --- /dev/null +++ b/tests/struct_integers.rs @@ -0,0 +1,35 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Eq, PartialEq, Serialize, Deserialize)] +struct S { + a: i8, + b: i16, + c: i32, + d: i64, + e: i128, + f: u8, + g: u16, + h: u32, + i: u64, + j: u128, +} + +#[test] +fn roundtrip() { + let s = S { + a: i8::MIN, + b: i16::MIN, + c: i32::MIN, + d: i64::MIN, + e: i128::MIN, + f: u8::MAX, + g: u16::MAX, + h: u32::MAX, + i: u64::MAX, + j: u128::MAX, + }; + let serialized = ron::ser::to_string(&s).unwrap(); + dbg!(&serialized); + let deserialized = ron::de::from_str(&serialized).unwrap(); + assert_eq!(s, deserialized,); +}