Skip to content
This repository has been archived by the owner on Mar 25, 2024. It is now read-only.

Commit

Permalink
Merge pull request #110 from asomers/i128
Browse files Browse the repository at this point in the history
128-bit integer support
  • Loading branch information
dtolnay committed Oct 14, 2018
2 parents 29d54cc + 3df4cce commit e689e30
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Expand Up @@ -12,7 +12,7 @@ keywords = ["yaml", "serde"]
[dependencies]
dtoa = "0.4"
linked-hash-map = "0.5"
serde = "1.0"
serde = "1.0.60"
yaml-rust = "0.4"

[dev-dependencies]
Expand Down
28 changes: 28 additions & 0 deletions src/de.rs
Expand Up @@ -565,9 +565,19 @@ where
if let Ok(n) = v.parse() {
return visitor.visit_u64(n);
}
serde_if_integer128! {
if let Ok(n) = v.parse() {
return visitor.visit_u128(n);
}
}
if let Ok(n) = v.parse() {
return visitor.visit_i64(n);
}
serde_if_integer128! {
if let Ok(n) = v.parse() {
return visitor.visit_i128(n);
}
}
match v.trim_left_matches('+') {
".inf" | ".Inf" | ".INF" => return visitor.visit_f64(f64::INFINITY),
_ => (),
Expand Down Expand Up @@ -685,6 +695,15 @@ impl<'de, 'a, 'r> de::Deserializer<'de> for &'r mut Deserializer<'a> {
self.deserialize_scalar(visitor)
}

serde_if_integer128! {
fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.deserialize_scalar(visitor)
}
}

fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
Expand Down Expand Up @@ -713,6 +732,15 @@ impl<'de, 'a, 'r> de::Deserializer<'de> for &'r mut Deserializer<'a> {
self.deserialize_scalar(visitor)
}

serde_if_integer128! {
fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.deserialize_scalar(visitor)
}
}

fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
Expand Down
8 changes: 4 additions & 4 deletions src/number.rs
Expand Up @@ -436,8 +436,8 @@ impl<'de> Deserializer<'de> for Number {
}

forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
byte_buf option unit unit_struct newtype_struct seq tuple
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
bytes byte_buf option unit unit_struct newtype_struct seq tuple
tuple_struct map struct enum identifier ignored_any
}
}
Expand All @@ -458,8 +458,8 @@ impl<'de, 'a> Deserializer<'de> for &'a Number {
}

forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
byte_buf option unit unit_struct newtype_struct seq tuple
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
bytes byte_buf option unit unit_struct newtype_struct seq tuple
tuple_struct map struct enum identifier ignored_any
}
}
Expand Down
22 changes: 22 additions & 0 deletions src/ser.rs
Expand Up @@ -53,6 +53,17 @@ impl ser::Serializer for Serializer {
Ok(Yaml::Integer(v))
}

serde_if_integer128! {
#[cfg_attr(feature = "cargo-clippy", allow(cast_possible_truncation))]
fn serialize_i128(self, v: i128) -> Result<Yaml> {
if v <= i64::max_value() as i128 && v >= i64::min_value() as i128 {
self.serialize_i64(v as i64)
} else {
Ok(Yaml::Real(v.to_string()))
}
}
}

fn serialize_u8(self, v: u8) -> Result<Yaml> {
self.serialize_i64(v as i64)
}
Expand All @@ -73,6 +84,17 @@ impl ser::Serializer for Serializer {
}
}

serde_if_integer128! {
#[cfg_attr(feature = "cargo-clippy", allow(cast_possible_truncation))]
fn serialize_u128(self, v: u128) -> Result<Yaml> {
if v <= i64::max_value() as u128 {
self.serialize_i64(v as i64)
} else {
Ok(Yaml::Real(v.to_string()))
}
}
}

fn serialize_f32(self, v: f32) -> Result<Yaml> {
self.serialize_f64(v as f64)
}
Expand Down
18 changes: 18 additions & 0 deletions src/value/de.rs
Expand Up @@ -213,6 +213,15 @@ impl<'de> Deserializer<'de> for Value {
self.deserialize_number(visitor)
}

serde_if_integer128! {
fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
self.deserialize_number(visitor)
}
}

fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
Expand Down Expand Up @@ -241,6 +250,15 @@ impl<'de> Deserializer<'de> for Value {
self.deserialize_number(visitor)
}

serde_if_integer128! {
fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
self.deserialize_number(visitor)
}
}

fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
Expand Down
2 changes: 1 addition & 1 deletion src/value/mod.rs
Expand Up @@ -311,7 +311,7 @@ impl Value {
self.as_u64().is_some()
}

/// If the `Value` is an integer, represent it as i64 if possible. Returns
/// If the `Value` is an integer, represent it as u64 if possible. Returns
/// None otherwise.
///
/// ```rust
Expand Down
31 changes: 29 additions & 2 deletions tests/test_de.rs
Expand Up @@ -9,7 +9,9 @@
#[macro_use]
extern crate serde_derive;

#[macro_use]
extern crate serde;

extern crate serde_yaml;

extern crate unindent;
Expand Down Expand Up @@ -169,14 +171,39 @@ fn test_number_as_string() {
let yaml = unindent(
"
---
value: 123456789012345678901234567890",
# Cannot be represented as u128
value: 340282366920938463463374607431768211457",
);
let expected = Num {
value: "123456789012345678901234567890".to_owned(),
value: "340282366920938463463374607431768211457".to_owned(),
};
test_de(&yaml, &expected);
}

serde_if_integer128! {
#[test]
fn test_i128_big() {
let expected: i128 = ::std::i64::MIN as i128 - 1;
let yaml = unindent(
"
---
-9223372036854775809",
);
assert_eq!(expected, serde_yaml::from_str::<i128>(&yaml).unwrap());
}

#[test]
fn test_u128_big() {
let expected: u128 = ::std::u64::MAX as u128 + 1;
let yaml = unindent(
"
---
18446744073709551616",
);
assert_eq!(expected, serde_yaml::from_str::<u128>(&yaml).unwrap());
}
}

#[test]
fn test_number_alias_as_string() {
#[derive(Deserialize, PartialEq, Debug)]
Expand Down
26 changes: 26 additions & 0 deletions tests/test_serde.rs
Expand Up @@ -14,7 +14,9 @@
#[macro_use]
extern crate serde_derive;

#[macro_use]
extern crate serde;

extern crate serde_yaml;

extern crate unindent;
Expand Down Expand Up @@ -91,6 +93,30 @@ fn test_int_max_i64() {
test_serde(&thing, &yaml);
}

serde_if_integer128! {
#[test]
fn test_i128_small() {
let thing: i128 = -256;
let yaml = unindent(
"
---
-256",
);
test_serde(&thing, &yaml);
}

#[test]
fn test_u128_small() {
let thing: u128 = 256;
let yaml = unindent(
"
---
256",
);
test_serde(&thing, &yaml);
}
}

#[test]
fn test_float() {
let thing = 25.6;
Expand Down

0 comments on commit e689e30

Please sign in to comment.