Skip to content

Commit f39088c

Browse files
committed
u128/i128
1 parent f9c4075 commit f39088c

File tree

3 files changed

+92
-19
lines changed

3 files changed

+92
-19
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "json5"
3-
version = "1.0.0"
3+
version = "1.1.0"
44
authors = ["Callum Oakley <hello@callumoakley.net>"]
55
description = "A Rust JSON5 serializer and deserializer which speaks Serde."
66
license = "MIT"

src/de.rs

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ impl<'de> Deserializer<'de> {
250250
.parse_decimal_number(neg, start, offset)
251251
.map(|n| (start, n)),
252252
Some((_, '0'..='9')) => Err(self.err_at(start, ErrorCode::LeadingZero)),
253-
_ => Ok((start, NumberResult::U64(0))),
253+
_ => Ok((start, NumberResult::U128(0))),
254254
},
255255
(offset, '.' | '1'..='9') => self
256256
.parse_decimal_number(neg, start, offset)
@@ -279,10 +279,10 @@ impl<'de> Deserializer<'de> {
279279
Ok(NumberResult::F64(self.parse_from_str(start, offset)?))
280280
} else if neg {
281281
// https://doc.rust-lang.org/std/primitive.i64.html#method.from_str
282-
Ok(NumberResult::I64(self.parse_from_str(start, offset)?))
282+
Ok(NumberResult::I128(self.parse_from_str(start, offset)?))
283283
} else {
284284
// https://doc.rust-lang.org/std/primitive.u64.html#method.from_str
285-
Ok(NumberResult::U64(self.parse_from_str(start, offset)?))
285+
Ok(NumberResult::U128(self.parse_from_str(start, offset)?))
286286
}
287287
}
288288

@@ -301,7 +301,7 @@ impl<'de> Deserializer<'de> {
301301
if !c.is_ascii_hexdigit() {
302302
return Err(self.err_at(offset, ErrorCode::ExpectedNumber));
303303
}
304-
let mut n = u64::from(c.to_digit(16).expect("c is ascii hexdigit"));
304+
let mut n = u128::from(c.to_digit(16).expect("c is ascii hexdigit"));
305305

306306
while let Some((offset, c)) = self.peek()
307307
&& c.is_ascii_hexdigit()
@@ -310,22 +310,22 @@ impl<'de> Deserializer<'de> {
310310
n = n
311311
.checked_mul(16)
312312
.and_then(|n| {
313-
n.checked_add(u64::from(c.to_digit(16).expect("c is ascii hexdigit")))
313+
n.checked_add(u128::from(c.to_digit(16).expect("c is ascii hexdigit")))
314314
})
315315
.ok_or(self.err_at(offset, ErrorCode::OverflowParsingNumber))?;
316316
}
317317

318318
if neg {
319-
// Special case for i64::MIN because -i64::MIN = i64::MAX + 1 doesn't fit in an i64.
320-
if n == 0x8000_0000_0000_0000 {
321-
Ok(NumberResult::I64(i64::MIN))
319+
// Special case for i128::MIN because -i128::MIN = i128::MAX + 1 doesn't fit in an i128.
320+
if n == 0x8000_0000_0000_0000_0000_0000_0000_0000 {
321+
Ok(NumberResult::I128(i128::MIN))
322322
} else {
323-
Ok(NumberResult::I64(
324-
-i64::try_from(n).map_err(|err| self.custom_err_at(start, err))?,
323+
Ok(NumberResult::I128(
324+
-i128::try_from(n).map_err(|err| self.custom_err_at(start, err))?,
325325
))
326326
}
327327
} else {
328-
Ok(NumberResult::U64(n))
328+
Ok(NumberResult::U128(n))
329329
}
330330
}
331331

@@ -509,8 +509,20 @@ macro_rules! deserialize_number {
509509
fn $method<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
510510
let (offset, number) = self.parse_number()?;
511511
match number {
512-
NumberResult::U64(u) => visitor.visit_u64(u),
513-
NumberResult::I64(i) => visitor.visit_i64(i),
512+
NumberResult::U128(u) => {
513+
if let Ok(u) = u64::try_from(u) {
514+
visitor.visit_u64(u)
515+
} else {
516+
visitor.visit_u128(u)
517+
}
518+
}
519+
NumberResult::I128(i) => {
520+
if let Ok(i) = i64::try_from(i) {
521+
visitor.visit_i64(i)
522+
} else {
523+
visitor.visit_i128(i)
524+
}
525+
}
514526
NumberResult::F64(f) => visitor.visit_f64(f),
515527
}
516528
.map_err(|err| self.with_position(err, offset))
@@ -575,10 +587,12 @@ impl<'de> serde::de::Deserializer<'de> for &mut Deserializer<'de> {
575587
deserialize_number!(deserialize_u16);
576588
deserialize_number!(deserialize_u32);
577589
deserialize_number!(deserialize_u64);
590+
deserialize_number!(deserialize_u128);
578591
deserialize_number!(deserialize_i8);
579592
deserialize_number!(deserialize_i16);
580593
deserialize_number!(deserialize_i32);
581594
deserialize_number!(deserialize_i64);
595+
deserialize_number!(deserialize_i128);
582596
deserialize_number!(deserialize_f32);
583597
deserialize_number!(deserialize_f64);
584598

@@ -844,10 +858,12 @@ impl<'de> serde::de::Deserializer<'de> for MapKey<'_, 'de> {
844858
deserialize_key_from_str!(deserialize_u16, visit_u16);
845859
deserialize_key_from_str!(deserialize_u32, visit_u32);
846860
deserialize_key_from_str!(deserialize_u64, visit_u64);
861+
deserialize_key_from_str!(deserialize_u128, visit_u128);
847862
deserialize_key_from_str!(deserialize_i8, visit_i8);
848863
deserialize_key_from_str!(deserialize_i16, visit_i16);
849864
deserialize_key_from_str!(deserialize_i32, visit_i32);
850865
deserialize_key_from_str!(deserialize_i64, visit_i64);
866+
deserialize_key_from_str!(deserialize_i128, visit_i128);
851867
deserialize_key_from_str!(deserialize_f32, visit_f32);
852868
deserialize_key_from_str!(deserialize_f64, visit_f64);
853869

@@ -1031,7 +1047,7 @@ impl Deref for StringResult<'_> {
10311047
}
10321048

10331049
enum NumberResult {
1034-
U64(u64),
1035-
I64(i64),
1050+
U128(u128),
1051+
I128(i128),
10361052
F64(f64),
10371053
}

tests/de.rs

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,19 @@ fn parse_bool() {
5353
fn parse_number() {
5454
assert_eq!(from_str("0"), Ok(0));
5555
assert!(from_str::<f64>("-0.").is_ok_and(|f| f == 0. && f.is_sign_negative()));
56+
assert_eq!(from_str("123"), Ok(123i8));
57+
assert_eq!(from_str("123"), Ok(123u8));
58+
assert_eq!(from_str("123"), Ok(123i16));
59+
assert_eq!(from_str("123"), Ok(123u16));
5660
assert_eq!(from_str("123"), Ok(123i32));
5761
assert_eq!(from_str("123"), Ok(123u32));
62+
assert_eq!(from_str("123"), Ok(123i64));
63+
assert_eq!(from_str("123"), Ok(123u64));
64+
assert_eq!(from_str("123"), Ok(123i128));
65+
assert_eq!(from_str("123"), Ok(123u128));
5866
assert_eq!(from_str("-123"), Ok(-123));
59-
assert_eq!(from_str("123.456"), Ok(123.456));
67+
assert_eq!(from_str("123.456"), Ok(123.456f32));
68+
assert_eq!(from_str("123.456"), Ok(123.456f64));
6069
assert_eq!(from_str("123.0"), Ok(123.));
6170
assert_eq!(from_str("123."), Ok(123.));
6271
assert_eq!(from_str(".456"), Ok(0.456));
@@ -73,13 +82,33 @@ fn parse_number() {
7382
assert_eq!(from_str("0x7FFFFFFFFFFFFFFF"), Ok(i64::MAX));
7483
assert_eq!(from_str("-0x8000000000000000"), Ok(i64::MIN));
7584
assert_eq!(from_str("0x0"), Ok(0));
85+
assert_eq!(
86+
from_str("340282366920938463463374607431768211455"),
87+
Ok(u128::MAX)
88+
);
89+
assert_eq!(
90+
from_str("-170141183460469231731687303715884105728"),
91+
Ok(i128::MIN)
92+
);
93+
assert_eq!(
94+
from_str("0xffffffffffffffffffffffffffffffff"),
95+
Ok(u128::MAX)
96+
);
97+
assert_eq!(
98+
from_str("-0x80000000000000000000000000000000"),
99+
Ok(i128::MIN)
100+
);
76101

77102
assert_eq!(from_str::<u32>("0x"), Err(err(EofParsingNumber)));
78103
assert_eq!(from_str::<u32>("0x!"), Err(err_at(0, 2, ExpectedNumber)));
79104
assert_eq!(from_str::<f64>("inf"), Err(err_at(0, 0, ExpectedNumber)));
80105
assert_eq!(
81106
from_str::<u64>("0x10000000000000000"), // u64::MAX + 1
82-
Err(err_at(0, 18, OverflowParsingNumber))
107+
Err(custom_err_at(
108+
0,
109+
0,
110+
"invalid type: integer `18446744073709551616` as u128, expected u64"
111+
))
83112
);
84113
assert_eq!(
85114
from_str::<u32>("007"),
@@ -90,7 +119,7 @@ fn parse_number() {
90119
Err(custom_err_at(
91120
0,
92121
0,
93-
"number too large to fit in target type"
122+
"invalid type: integer `18446744073709551616` as u128, expected u64"
94123
))
95124
);
96125
assert_eq!(
@@ -103,6 +132,34 @@ fn parse_number() {
103132
);
104133
assert_eq!(
105134
from_str::<i64>("-0x8000000000000001"), // i64::MIN - 1
135+
Err(custom_err_at(
136+
0,
137+
0,
138+
"invalid type: integer `-9223372036854775809` as i128, expected i64"
139+
))
140+
);
141+
assert_eq!(
142+
from_str::<i64>("340282366920938463463374607431768211456"), // u128::MAX + 1
143+
Err(custom_err_at(
144+
0,
145+
0,
146+
"number too large to fit in target type"
147+
))
148+
);
149+
assert_eq!(
150+
from_str::<i64>("-170141183460469231731687303715884105729"), // i128::MIN - 1
151+
Err(custom_err_at(
152+
0,
153+
0,
154+
"number too small to fit in target type"
155+
))
156+
);
157+
assert_eq!(
158+
from_str::<u128>("0x100000000000000000000000000000000"), // u128::MAX + 1
159+
Err(err_at(0, 34, OverflowParsingNumber))
160+
);
161+
assert_eq!(
162+
from_str::<i128>("-0x80000000000000000000000000000001"), // i128::MIN - 1
106163
Err(custom_err_at(
107164
0,
108165
0,

0 commit comments

Comments
 (0)