Skip to content

Commit b279ebb

Browse files
authored
Merge pull request #1263 from serde-rs/integer128
Add Serde impls for i128 and u128
2 parents 039ebc6 + 9083cf4 commit b279ebb

File tree

13 files changed

+504
-80
lines changed

13 files changed

+504
-80
lines changed

serde/src/de/from_primitive.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,3 +178,91 @@ impl_from_primitive_for_uint!(u32);
178178
impl_from_primitive_for_uint!(u64);
179179
impl_from_primitive_for_float!(f32);
180180
impl_from_primitive_for_float!(f64);
181+
182+
serde_if_integer128! {
183+
impl FromPrimitive for i128 {
184+
#[inline]
185+
fn from_i8(n: i8) -> Option<Self> {
186+
Some(n as i128)
187+
}
188+
#[inline]
189+
fn from_i16(n: i16) -> Option<Self> {
190+
Some(n as i128)
191+
}
192+
#[inline]
193+
fn from_i32(n: i32) -> Option<Self> {
194+
Some(n as i128)
195+
}
196+
#[inline]
197+
fn from_i64(n: i64) -> Option<Self> {
198+
Some(n as i128)
199+
}
200+
#[inline]
201+
fn from_u8(n: u8) -> Option<Self> {
202+
Some(n as i128)
203+
}
204+
#[inline]
205+
fn from_u16(n: u16) -> Option<Self> {
206+
Some(n as i128)
207+
}
208+
#[inline]
209+
fn from_u32(n: u32) -> Option<Self> {
210+
Some(n as i128)
211+
}
212+
#[inline]
213+
fn from_u64(n: u64) -> Option<Self> {
214+
Some(n as i128)
215+
}
216+
}
217+
218+
impl FromPrimitive for u128 {
219+
#[inline]
220+
fn from_i8(n: i8) -> Option<Self> {
221+
if n >= 0 {
222+
Some(n as u128)
223+
} else {
224+
None
225+
}
226+
}
227+
#[inline]
228+
fn from_i16(n: i16) -> Option<Self> {
229+
if n >= 0 {
230+
Some(n as u128)
231+
} else {
232+
None
233+
}
234+
}
235+
#[inline]
236+
fn from_i32(n: i32) -> Option<Self> {
237+
if n >= 0 {
238+
Some(n as u128)
239+
} else {
240+
None
241+
}
242+
}
243+
#[inline]
244+
fn from_i64(n: i64) -> Option<Self> {
245+
if n >= 0 {
246+
Some(n as u128)
247+
} else {
248+
None
249+
}
250+
}
251+
#[inline]
252+
fn from_u8(n: u8) -> Option<Self> {
253+
Some(n as u128)
254+
}
255+
#[inline]
256+
fn from_u16(n: u16) -> Option<Self> {
257+
Some(n as u128)
258+
}
259+
#[inline]
260+
fn from_u32(n: u32) -> Option<Self> {
261+
Some(n as u128)
262+
}
263+
#[inline]
264+
fn from_u64(n: u64) -> Option<Self> {
265+
Some(n as u128)
266+
}
267+
}
268+
}

serde/src/de/impls.rs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,92 @@ impl_deserialize_num!(usize, deserialize_u64, integer);
166166
impl_deserialize_num!(f32, deserialize_f32, integer, float);
167167
impl_deserialize_num!(f64, deserialize_f64, integer, float);
168168

169+
serde_if_integer128! {
170+
impl<'de> Deserialize<'de> for i128 {
171+
#[inline]
172+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
173+
where
174+
D: Deserializer<'de>,
175+
{
176+
struct PrimitiveVisitor;
177+
178+
impl<'de> Visitor<'de> for PrimitiveVisitor {
179+
type Value = i128;
180+
181+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
182+
formatter.write_str("i128")
183+
}
184+
185+
impl_deserialize_num!(integer i128);
186+
187+
#[inline]
188+
fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
189+
where
190+
E: Error,
191+
{
192+
Ok(v)
193+
}
194+
195+
#[inline]
196+
fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
197+
where
198+
E: Error,
199+
{
200+
if v <= i128::max_value() as u128 {
201+
Ok(v as i128)
202+
} else {
203+
Err(Error::invalid_value(Unexpected::Other("u128"), &self))
204+
}
205+
}
206+
}
207+
208+
deserializer.deserialize_i128(PrimitiveVisitor)
209+
}
210+
}
211+
212+
impl<'de> Deserialize<'de> for u128 {
213+
#[inline]
214+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
215+
where
216+
D: Deserializer<'de>,
217+
{
218+
struct PrimitiveVisitor;
219+
220+
impl<'de> Visitor<'de> for PrimitiveVisitor {
221+
type Value = u128;
222+
223+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
224+
formatter.write_str("u128")
225+
}
226+
227+
impl_deserialize_num!(integer u128);
228+
229+
#[inline]
230+
fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
231+
where
232+
E: Error,
233+
{
234+
if v >= 0 {
235+
Ok(v as u128)
236+
} else {
237+
Err(Error::invalid_value(Unexpected::Other("i128"), &self))
238+
}
239+
}
240+
241+
#[inline]
242+
fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
243+
where
244+
E: Error,
245+
{
246+
Ok(v)
247+
}
248+
}
249+
250+
deserializer.deserialize_u128(PrimitiveVisitor)
251+
}
252+
}
253+
}
254+
169255
////////////////////////////////////////////////////////////////////////////////
170256

171257
struct CharVisitor;

serde/src/de/mod.rs

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@
5252
//!
5353
//! - **Primitive types**:
5454
//! - bool
55-
//! - i8, i16, i32, i64, isize
56-
//! - u8, u16, u32, u64, usize
55+
//! - i8, i16, i32, i64, i128, isize
56+
//! - u8, u16, u32, u64, u128, usize
5757
//! - f32, f64
5858
//! - char
5959
//! - **Compound types**:
@@ -757,7 +757,7 @@ where
757757
/// Serde.
758758
///
759759
/// The role of this trait is to define the deserialization half of the Serde
760-
/// data model, which is a way to categorize every Rust data type into one of 27
760+
/// data model, which is a way to categorize every Rust data type into one of 29
761761
/// possible types. Each method of the `Serializer` trait corresponds to one of
762762
/// the types of the data model.
763763
///
@@ -767,10 +767,10 @@ where
767767
///
768768
/// The types that make up the Serde data model are:
769769
///
770-
/// - **12 primitive types**
770+
/// - **14 primitive types**
771771
/// - bool
772-
/// - i8, i16, i32, i64
773-
/// - u8, u16, u32, u64
772+
/// - i8, i16, i32, i64, i128
773+
/// - u8, u16, u32, u64, u128
774774
/// - f32, f64
775775
/// - char
776776
/// - **string**
@@ -884,6 +884,20 @@ pub trait Deserializer<'de>: Sized {
884884
where
885885
V: Visitor<'de>;
886886

887+
serde_if_integer128! {
888+
/// Hint that the `Deserialize` type is expecting an `i128` value.
889+
///
890+
/// This method is available only on Rust compiler versions >=1.26. The
891+
/// default behavior unconditionally returns an error.
892+
fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value, Self::Error>
893+
where
894+
V: Visitor<'de>
895+
{
896+
let _ = visitor;
897+
Err(Error::custom("i128 is not supported"))
898+
}
899+
}
900+
887901
/// Hint that the `Deserialize` type is expecting a `u8` value.
888902
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
889903
where
@@ -904,6 +918,20 @@ pub trait Deserializer<'de>: Sized {
904918
where
905919
V: Visitor<'de>;
906920

921+
serde_if_integer128! {
922+
/// Hint that the `Deserialize` type is expecting an `u128` value.
923+
///
924+
/// This method is available only on Rust compiler versions >=1.26. The
925+
/// default behavior unconditionally returns an error.
926+
fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value, Self::Error>
927+
where
928+
V: Visitor<'de>
929+
{
930+
let _ = visitor;
931+
Err(Error::custom("u128 is not supported"))
932+
}
933+
}
934+
907935
/// Hint that the `Deserialize` type is expecting a `f32` value.
908936
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
909937
where
@@ -1250,6 +1278,20 @@ pub trait Visitor<'de>: Sized {
12501278
Err(Error::invalid_type(Unexpected::Signed(v), &self))
12511279
}
12521280

1281+
serde_if_integer128! {
1282+
/// The input contains a `i128`.
1283+
///
1284+
/// This method is available only on Rust compiler versions >=1.26. The
1285+
/// default implementation fails with a type error.
1286+
fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
1287+
where
1288+
E: Error,
1289+
{
1290+
let _ = v;
1291+
Err(Error::invalid_type(Unexpected::Other("i128"), &self))
1292+
}
1293+
}
1294+
12531295
/// The input contains a `u8`.
12541296
///
12551297
/// The default implementation forwards to [`visit_u64`].
@@ -1296,6 +1338,20 @@ pub trait Visitor<'de>: Sized {
12961338
Err(Error::invalid_type(Unexpected::Unsigned(v), &self))
12971339
}
12981340

1341+
serde_if_integer128! {
1342+
/// The input contains a `u128`.
1343+
///
1344+
/// This method is available only on Rust compiler versions >=1.26. The
1345+
/// default implementation fails with a type error.
1346+
fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
1347+
where
1348+
E: Error,
1349+
{
1350+
let _ = v;
1351+
Err(Error::invalid_type(Unexpected::Other("u128"), &self))
1352+
}
1353+
}
1354+
12991355
/// The input contains an `f32`.
13001356
///
13011357
/// The default implementation forwards to [`visit_f64`].

0 commit comments

Comments
 (0)