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

128-bit integer support #110

Merged
merged 6 commits into from Oct 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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