diff --git a/src/de.rs b/src/de.rs index 85fe2f18..77d05282 100644 --- a/src/de.rs +++ b/src/de.rs @@ -85,6 +85,11 @@ impl<'de> de::Deserializer<'de> for Value { visitor.visit_i64(num) } + #[inline] + fn deserialize_i128>(self, visitor: V) -> Result { + visitor.visit_i128(self.into_int128()?) + } + #[inline] fn deserialize_u8>(self, visitor: V) -> Result { let num = try_convert_number!(unsigned, self, "8"); @@ -109,6 +114,11 @@ impl<'de> de::Deserializer<'de> for Value { visitor.visit_u64(num) } + #[inline] + fn deserialize_u128>(self, visitor: V) -> Result { + visitor.visit_u128(self.into_uint128()?) + } + #[inline] fn deserialize_f32>(self, visitor: V) -> Result { visitor.visit_f32(self.into_float()? as f32) diff --git a/src/ser.rs b/src/ser.rs index 211717a5..ecdabc64 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -108,6 +108,10 @@ impl<'a> ser::Serializer for &'a mut ConfigSerializer { self.serialize_primitive(v) } + fn serialize_i128(self, v: i128) -> Result { + self.serialize_primitive(v) + } + fn serialize_u8(self, v: u8) -> Result { self.serialize_u64(v.into()) } @@ -124,6 +128,10 @@ impl<'a> ser::Serializer for &'a mut ConfigSerializer { self.serialize_primitive(v) } + fn serialize_u128(self, v: u128) -> Result { + self.serialize_primitive(v) + } + fn serialize_f32(self, v: f32) -> Result { self.serialize_f64(v.into()) } diff --git a/src/value.rs b/src/value.rs index b207c761..f0ecee85 100644 --- a/src/value.rs +++ b/src/value.rs @@ -276,21 +276,21 @@ impl Value { ConfigError::invalid_type( self.origin, Unexpected::I128(value), - "an signed 64 bit or less integer", + "a signed 64 bit or less integer", ) }), ValueKind::U64(value) => value.try_into().map_err(|_| { ConfigError::invalid_type( self.origin, Unexpected::U64(value), - "an signed 64 bit or less integer", + "a signed 64 bit or less integer", ) }), ValueKind::U128(value) => value.try_into().map_err(|_| { ConfigError::invalid_type( self.origin, Unexpected::U128(value), - "an signed 64 bit or less integer", + "a signed 64 bit or less integer", ) }), @@ -343,7 +343,7 @@ impl Value { ConfigError::invalid_type( self.origin, Unexpected::U128(value), - "an signed 128 bit integer", + "a signed 128 bit integer", ) }), diff --git a/tests/testsuite/integer_range.rs b/tests/testsuite/integer_range.rs index 535de2cb..8fb94fe9 100644 --- a/tests/testsuite/integer_range.rs +++ b/tests/testsuite/integer_range.rs @@ -68,3 +68,81 @@ fn invalid_signedness() { let _: u32 = c.get("settings.port").unwrap(); } + +#[cfg(feature = "preserve_order")] +#[test] +fn serde_i128_min() { + use serde::{Deserialize, Serialize}; + + #[derive(Debug, Deserialize, Eq, PartialEq, Serialize)] + struct Container { + inner: T, + } + + #[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)] + struct I128 { + val: i128, + } + + impl From for config::ValueKind { + fn from(i: I128) -> Self { + let mut properties = indexmap::IndexMap::new(); + properties.insert("val".to_owned(), config::Value::from(i.val)); + + Self::Table(properties) + } + } + + let num = I128 { val: i128::MIN }; + let container = Container { inner: num }; + let built = Config::builder() + .set_default("inner", num) + .unwrap() + .build() + .unwrap(); + + let deserialized = built.clone().try_deserialize::>().unwrap(); + assert_eq!(deserialized, container); + + let serialized = Config::try_from(&container).unwrap(); + assert_eq!(serialized.cache, built.cache); +} + +#[cfg(feature = "preserve_order")] +#[test] +fn serde_u128_max() { + use serde::{Deserialize, Serialize}; + + #[derive(Debug, Deserialize, Eq, PartialEq, Serialize)] + struct Container { + inner: T, + } + + #[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)] + struct U128 { + val: u128, + } + + impl From for config::ValueKind { + fn from(i: U128) -> Self { + let mut properties = indexmap::IndexMap::new(); + properties.insert("val".to_owned(), config::Value::from(i.val)); + + Self::Table(properties) + } + } + + let num = U128 { val: u128::MAX }; + let container = Container { inner: num }; + let built = Config::builder() + .set_default("inner", num) + .unwrap() + .build() + .unwrap(); + + let deserialized = built.clone().try_deserialize::>().unwrap(); + assert_eq!(deserialized, container); + + let serialized = Config::try_from(&container).unwrap(); + assert_eq!(serialized.cache, built.cache); +}