Skip to content

Commit e06fd8c

Browse files
committed
fix: add missing support for 128-bit integers
1 parent 0cc776e commit e06fd8c

File tree

6 files changed

+115
-1
lines changed

6 files changed

+115
-1
lines changed

src/de.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ impl<'de> de::Deserializer<'de> for Value {
8585
visitor.visit_i64(num)
8686
}
8787

88+
#[inline]
89+
fn deserialize_i128<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
90+
visitor.visit_i128(self.into_int128()?)
91+
}
92+
8893
#[inline]
8994
fn deserialize_u8<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
9095
let num = try_convert_number!(unsigned, self, "8");
@@ -109,6 +114,11 @@ impl<'de> de::Deserializer<'de> for Value {
109114
visitor.visit_u64(num)
110115
}
111116

117+
#[inline]
118+
fn deserialize_u128<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
119+
visitor.visit_u128(self.into_uint128()?)
120+
}
121+
112122
#[inline]
113123
fn deserialize_f32<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
114124
visitor.visit_f32(self.into_float()? as f32)

src/ser.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,24 @@ impl<'a> ser::Serializer for &'a mut ConfigSerializer {
108108
self.serialize_primitive(v)
109109
}
110110

111+
fn serialize_i128(self, v: i128) -> Result<Self::Ok> {
112+
if v > i64::MAX.into() {
113+
Err(ConfigError::Message(format!(
114+
"value {} is greater than the max {}",
115+
v,
116+
i64::MAX
117+
)))
118+
} else if v < i64::MIN.into() {
119+
Err(ConfigError::Message(format!(
120+
"value {} is less than the min {}",
121+
v,
122+
i64::MIN
123+
)))
124+
} else {
125+
self.serialize_i64(v as i64)
126+
}
127+
}
128+
111129
fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
112130
self.serialize_u64(v.into())
113131
}
@@ -132,6 +150,18 @@ impl<'a> ser::Serializer for &'a mut ConfigSerializer {
132150
}
133151
}
134152

153+
fn serialize_u128(self, v: u128) -> Result<Self::Ok> {
154+
if v > (i64::MAX as u128) {
155+
Err(ConfigError::Message(format!(
156+
"value {} is greater than the max {}",
157+
v,
158+
i64::MAX
159+
)))
160+
} else {
161+
self.serialize_i64(v as i64)
162+
}
163+
}
164+
135165
fn serialize_f32(self, v: f32) -> Result<Self::Ok> {
136166
self.serialize_f64(v.into())
137167
}

src/value.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ impl Value {
343343
ConfigError::invalid_type(
344344
self.origin,
345345
Unexpected::U128(value),
346-
"an signed 128 bit integer",
346+
"a signed 128 bit integer",
347347
)
348348
}),
349349

tests/testsuite/i128.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#![cfg(feature = "preserve_order")]
2+
3+
use serde::Deserialize;
4+
5+
#[derive(Debug, Deserialize, Eq, PartialEq)]
6+
struct Container<T> {
7+
inner: T,
8+
}
9+
10+
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq)]
11+
struct I128 {
12+
val: i128,
13+
}
14+
15+
impl From<I128> for config::ValueKind {
16+
fn from(i: I128) -> Self {
17+
let mut properties = indexmap::IndexMap::new();
18+
properties.insert("val".to_owned(), config::Value::from(i.val));
19+
20+
Self::Table(properties)
21+
}
22+
}
23+
24+
#[test]
25+
fn test_deserialize_i128_min() {
26+
let num = I128 { val: i128::MIN };
27+
let container = Container { inner: num };
28+
let built = config::Config::builder()
29+
.set_default("inner", num)
30+
.unwrap()
31+
.build()
32+
.unwrap();
33+
34+
let deserialized = built.clone().try_deserialize::<Container<I128>>().unwrap();
35+
assert_eq!(deserialized, container);
36+
}

tests/testsuite/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ pub mod file_ron;
1616
pub mod file_toml;
1717
pub mod file_yaml;
1818
pub mod get;
19+
pub mod i128;
1920
pub mod integer_range;
2021
pub mod log;
2122
pub mod merge;
2223
pub mod ron_enum;
2324
pub mod set;
25+
pub mod u128;
2426
pub mod unsigned_int;
2527
pub mod unsigned_int_hm;
2628
pub mod weird_keys;

tests/testsuite/u128.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#![cfg(feature = "preserve_order")]
2+
3+
use serde::Deserialize;
4+
5+
#[derive(Debug, Deserialize, Eq, PartialEq)]
6+
struct Container<T> {
7+
inner: T,
8+
}
9+
10+
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq)]
11+
struct U128 {
12+
val: u128,
13+
}
14+
15+
impl From<U128> for config::ValueKind {
16+
fn from(i: U128) -> Self {
17+
let mut properties = indexmap::IndexMap::new();
18+
properties.insert("val".to_owned(), config::Value::from(i.val));
19+
20+
Self::Table(properties)
21+
}
22+
}
23+
24+
#[test]
25+
fn test_deserialize_u128_min() {
26+
let num = U128 { val: u128::MIN };
27+
let container = Container { inner: num };
28+
let built = config::Config::builder()
29+
.set_default("inner", num)
30+
.unwrap()
31+
.build()
32+
.unwrap();
33+
34+
let deserialized = built.clone().try_deserialize::<Container<U128>>().unwrap();
35+
assert_eq!(deserialized, container);
36+
}

0 commit comments

Comments
 (0)