1 // Copyright 2017 Serde Developers
3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6 // option. This file may not be copied, modified, or distributed
7 // except according to those terms.
10 use num_traits
::NumCast
;
11 use serde
::de
::{self, Visitor, Unexpected}
;
12 use serde
::{Serialize, Serializer, Deserialize, Deserializer}
;
13 use std
::fmt
::{self, Debug, Display}
;
16 /// Represents a JSON number, whether integer or floating point.
17 #[derive(Clone, PartialEq)]
22 #[derive(Copy, Clone, PartialEq)]
25 /// Always less than zero.
32 /// Returns true if the `Number` is an integer between `i64::MIN` and
35 /// For any Number on which `is_i64` returns true, `as_i64` is guaranteed to
36 /// return the integer value.
40 /// # extern crate serde_json;
45 /// let big = i64::MAX as u64 + 10;
46 /// let v = json!({ "a": 64, "b": big, "c": 256.0 });
48 /// assert!(v["a"].is_i64());
50 /// // Greater than i64::MAX.
51 /// assert!(!v["b"].is_i64());
53 /// // Numbers with a decimal point are not considered integers.
54 /// assert!(!v["c"].is_i64());
58 pub fn is_i64(&self) -> bool
{
60 N
::PosInt(v
) => v
<= i64::MAX
as u64,
66 /// Returns true if the `Number` is an integer between zero and `u64::MAX`.
68 /// For any Number on which `is_u64` returns true, `as_u64` is guaranteed to
69 /// return the integer value.
73 /// # extern crate serde_json;
76 /// let v = json!({ "a": 64, "b": -64, "c": 256.0 });
78 /// assert!(v["a"].is_u64());
80 /// // Negative integer.
81 /// assert!(!v["b"].is_u64());
83 /// // Numbers with a decimal point are not considered integers.
84 /// assert!(!v["c"].is_u64());
88 pub fn is_u64(&self) -> bool
{
91 N
::NegInt(_
) | N
::Float(_
) => false,
95 /// Returns true if the `Number` can be represented by f64.
97 /// For any Number on which `is_f64` returns true, `as_f64` is guaranteed to
98 /// return the floating point value.
100 /// Currently this function returns true if and only if both `is_i64` and
101 /// `is_u64` return false but this is not a guarantee in the future.
105 /// # extern crate serde_json;
108 /// let v = json!({ "a": 256.0, "b": 64, "c": -64 });
110 /// assert!(v["a"].is_f64());
113 /// assert!(!v["b"].is_f64());
114 /// assert!(!v["c"].is_f64());
118 pub fn is_f64(&self) -> bool
{
121 N
::PosInt(_
) | N
::NegInt(_
) => false,
125 /// If the `Number` is an integer, represent it as i64 if possible. Returns
130 /// # extern crate serde_json;
135 /// let big = i64::MAX as u64 + 10;
136 /// let v = json!({ "a": 64, "b": big, "c": 256.0 });
138 /// assert_eq!(v["a"].as_i64(), Some(64));
139 /// assert_eq!(v["b"].as_i64(), None);
140 /// assert_eq!(v["c"].as_i64(), None);
144 pub fn as_i64(&self) -> Option
<i64> {
146 N
::PosInt(n
) => NumCast
::from(n
),
147 N
::NegInt(n
) => Some(n
),
152 /// If the `Number` is an integer, represent it as u64 if possible. Returns
157 /// # extern crate serde_json;
160 /// let v = json!({ "a": 64, "b": -64, "c": 256.0 });
162 /// assert_eq!(v["a"].as_u64(), Some(64));
163 /// assert_eq!(v["b"].as_u64(), None);
164 /// assert_eq!(v["c"].as_u64(), None);
168 pub fn as_u64(&self) -> Option
<u64> {
170 N
::PosInt(n
) => Some(n
),
171 N
::NegInt(n
) => NumCast
::from(n
),
176 /// Represents the number as f64 if possible. Returns None otherwise.
180 /// # extern crate serde_json;
183 /// let v = json!({ "a": 256.0, "b": 64, "c": -64 });
185 /// assert_eq!(v["a"].as_f64(), Some(256.0));
186 /// assert_eq!(v["b"].as_f64(), Some(64.0));
187 /// assert_eq!(v["c"].as_f64(), Some(-64.0));
191 pub fn as_f64(&self) -> Option
<f64> {
193 N
::PosInt(n
) => NumCast
::from(n
),
194 N
::NegInt(n
) => NumCast
::from(n
),
195 N
::Float(n
) => Some(n
),
199 /// Converts a finite `f64` to a `Number`. Infinite or NaN values are not JSON
205 /// # use serde_json::Number;
207 /// assert!(Number::from_f64(256.0).is_some());
209 /// assert!(Number::from_f64(f64::NAN).is_none());
212 pub fn from_f64(f
: f64) -> Option
<Number
> {
214 Some(Number { n: N::Float(f) }
)
221 impl fmt
::Display
for Number
{
222 fn fmt(&self, formatter
: &mut fmt
::Formatter
) -> fmt
::Result
{
224 N
::PosInt(i
) => Display
::fmt(&i
, formatter
),
225 N
::NegInt(i
) => Display
::fmt(&i
, formatter
),
226 N
::Float(f
) => Display
::fmt(&f
, formatter
),
231 impl Debug
for Number
{
232 fn fmt(&self, formatter
: &mut fmt
::Formatter
) -> fmt
::Result
{
233 let mut debug
= formatter
.debug_tuple("Number");
249 impl Serialize
for Number
{
251 fn serialize
<S
>(&self, serializer
: S
) -> Result
<S
::Ok
, S
::Error
>
256 N
::PosInt(i
) => serializer
.serialize_u64(i
),
257 N
::NegInt(i
) => serializer
.serialize_i64(i
),
258 N
::Float(f
) => serializer
.serialize_f64(f
),
263 impl<'de
> Deserialize
<'de
> for Number
{
265 fn deserialize
<D
>(deserializer
: D
) -> Result
<Number
, D
::Error
>
267 D
: Deserializer
<'de
>,
269 struct NumberVisitor
;
271 impl<'de
> Visitor
<'de
> for NumberVisitor
{
274 fn expecting(&self, formatter
: &mut fmt
::Formatter
) -> fmt
::Result
{
275 formatter
.write_str("a number")
279 fn visit_i64
<E
>(self, value
: i64) -> Result
<Number
, E
> {
284 fn visit_u64
<E
>(self, value
: u64) -> Result
<Number
, E
> {
289 fn visit_f64
<E
>(self, value
: f64) -> Result
<Number
, E
>
293 Number
::from_f64(value
).ok_or_else(|| de
::Error
::custom("not a JSON number"))
297 deserializer
.deserialize_any(NumberVisitor
)
301 impl<'de
> Deserializer
<'de
> for Number
{
305 fn deserialize_any
<V
>(self, visitor
: V
) -> Result
<V
::Value
, Error
>
310 N
::PosInt(i
) => visitor
.visit_u64(i
),
311 N
::NegInt(i
) => visitor
.visit_i64(i
),
312 N
::Float(f
) => visitor
.visit_f64(f
),
316 forward_to_deserialize_any
! {
317 bool
i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
318 byte_buf option unit unit_struct newtype_struct seq tuple
319 tuple_struct map
struct enum identifier ignored_any
323 impl<'de
, 'a
> Deserializer
<'de
> for &'a Number
{
327 fn deserialize_any
<V
>(self, visitor
: V
) -> Result
<V
::Value
, Error
>
332 N
::PosInt(i
) => visitor
.visit_u64(i
),
333 N
::NegInt(i
) => visitor
.visit_i64(i
),
334 N
::Float(f
) => visitor
.visit_f64(f
),
338 forward_to_deserialize_any
! {
339 bool
i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
340 byte_buf option unit unit_struct newtype_struct seq tuple
341 tuple_struct map
struct enum identifier ignored_any
345 macro_rules
! from_signed
{
346 ($
($signed_ty
:ident
)*) => {
348 impl From
<$signed_ty
> for Number
{
350 fn from(i
: $signed_ty
) -> Self {
352 Number { n: N::NegInt(i as i64) }
354 Number { n: N::PosInt(i as u64) }
362 macro_rules
! from_unsigned
{
363 ($
($unsigned_ty
:ident
)*) => {
365 impl From
<$unsigned_ty
> for Number
{
367 fn from(u
: $unsigned_ty
) -> Self {
368 Number { n: N::PosInt(u as u64) }
375 from_signed
!(i8 i16 i32 i64 isize);
376 from_unsigned
!(u8 u16 u32 u64 usize);
379 // Not public API. Should be pub(crate).
381 pub fn unexpected(&self) -> Unexpected
{
383 N
::PosInt(u
) => Unexpected
::Unsigned(u
),
384 N
::NegInt(i
) => Unexpected
::Signed(i
),
385 N
::Float(f
) => Unexpected
::Float(f
),