@@ -146,19 +146,6 @@ impl Number {
146
146
self . n . parse ( ) . ok ( )
147
147
}
148
148
149
- /// If the `Number` is an integer, represent it as i128 if possible. Returns
150
- /// None otherwise.
151
- pub fn as_i128 ( & self ) -> Option < i128 > {
152
- #[ cfg( not( feature = "arbitrary_precision" ) ) ]
153
- match self . n {
154
- N :: PosInt ( n) => Some ( n as i128 ) ,
155
- N :: NegInt ( n) => Some ( n as i128 ) ,
156
- N :: Float ( _) => None ,
157
- }
158
- #[ cfg( feature = "arbitrary_precision" ) ]
159
- self . n . parse ( ) . ok ( )
160
- }
161
-
162
149
/// If the `Number` is an integer, represent it as u64 if possible. Returns
163
150
/// None otherwise.
164
151
pub fn as_u64 ( & self ) -> Option < u64 > {
@@ -211,6 +198,31 @@ impl Number {
211
198
}
212
199
}
213
200
201
+ /// If the `Number` is an integer, represent it as i128 if possible. Returns
202
+ /// None otherwise.
203
+ pub fn as_i128 ( & self ) -> Option < i128 > {
204
+ #[ cfg( not( feature = "arbitrary_precision" ) ) ]
205
+ match self . n {
206
+ N :: PosInt ( n) => Some ( n as i128 ) ,
207
+ N :: NegInt ( n) => Some ( n as i128 ) ,
208
+ N :: Float ( _) => None ,
209
+ }
210
+ #[ cfg( feature = "arbitrary_precision" ) ]
211
+ self . n . parse ( ) . ok ( )
212
+ }
213
+
214
+ /// If the `Number` is an integer, represent it as u128 if possible. Returns
215
+ /// None otherwise.
216
+ pub fn as_u128 ( & self ) -> Option < u128 > {
217
+ #[ cfg( not( feature = "arbitrary_precision" ) ) ]
218
+ match self . n {
219
+ N :: PosInt ( n) => Some ( n as u128 ) ,
220
+ N :: NegInt ( _) | N :: Float ( _) => None ,
221
+ }
222
+ #[ cfg( feature = "arbitrary_precision" ) ]
223
+ self . n . parse ( ) . ok ( )
224
+ }
225
+
214
226
/// Converts an `i128` to a `Number`. Numbers smaller than i64::MIN or
215
227
/// larger than u64::MAX can only be represented in `Number` if serde_json's
216
228
/// "arbitrary_precision" feature is enabled.
@@ -240,6 +252,33 @@ impl Number {
240
252
Some ( Number { n } )
241
253
}
242
254
255
+ /// Converts a `u128` to a `Number`. Numbers greater than u64::MAX can only
256
+ /// be represented in `Number` if serde_json's "arbitrary_precision" feature
257
+ /// is enabled.
258
+ ///
259
+ /// ```
260
+ /// # use serde_json::Number;
261
+ /// #
262
+ /// assert!(Number::from_u128(256).is_some());
263
+ /// ```
264
+ pub fn from_u128 ( i : u128 ) -> Option < Number > {
265
+ let n = {
266
+ #[ cfg( not( feature = "arbitrary_precision" ) ) ]
267
+ {
268
+ if let Ok ( u) = u64:: try_from ( i) {
269
+ N :: PosInt ( u)
270
+ } else {
271
+ return None ;
272
+ }
273
+ }
274
+ #[ cfg( feature = "arbitrary_precision" ) ]
275
+ {
276
+ i. to_string ( )
277
+ }
278
+ } ;
279
+ Some ( Number { n } )
280
+ }
281
+
243
282
/// Returns the exact original JSON representation that this Number was
244
283
/// parsed from.
245
284
///
@@ -376,13 +415,22 @@ impl<'de> Deserialize<'de> for Number {
376
415
where
377
416
E : de:: Error ,
378
417
{
379
- Number :: from_i128 ( value) . ok_or_else ( || de:: Error :: custom ( "not a JSON number" ) )
418
+ Number :: from_i128 ( value)
419
+ . ok_or_else ( || de:: Error :: custom ( "JSON number out of range" ) )
380
420
}
381
421
382
422
fn visit_u64 < E > ( self , value : u64 ) -> Result < Number , E > {
383
423
Ok ( value. into ( ) )
384
424
}
385
425
426
+ fn visit_u128 < E > ( self , value : u128 ) -> Result < Number , E >
427
+ where
428
+ E : de:: Error ,
429
+ {
430
+ Number :: from_u128 ( value)
431
+ . ok_or_else ( || de:: Error :: custom ( "JSON number out of range" ) )
432
+ }
433
+
386
434
fn visit_f64 < E > ( self , value : f64 ) -> Result < Number , E >
387
435
where
388
436
E : de:: Error ,
@@ -503,6 +551,8 @@ macro_rules! deserialize_any {
503
551
return visitor. visit_u64( u) ;
504
552
} else if let Some ( i) = self . as_i64( ) {
505
553
return visitor. visit_i64( i) ;
554
+ } else if let Some ( u) = self . as_u128( ) {
555
+ return visitor. visit_u128( u) ;
506
556
} else if let Some ( i) = self . as_i128( ) {
507
557
return visitor. visit_i128( i) ;
508
558
} else if let Some ( f) = self . as_f64( ) {
0 commit comments