2 use num_traits
::NumCast
;
3 use serde
::de
::{self, Visitor}
;
4 use serde
::{Serialize, Serializer, Deserialize, Deserializer}
;
5 use std
::fmt
::{self, Debug, Display}
;
8 /// Represents a JSON number, whether integer or floating point.
9 #[derive(Clone, PartialEq)]
14 // "N" is a prefix of "NegInt"... this is a false positive.
15 // https://github.com/Manishearth/rust-clippy/issues/1241
16 #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
17 #[derive(Copy, Clone, Debug, PartialEq)]
20 /// Always less than zero.
27 /// Returns `true` if the number can be represented as `i64`.
29 pub fn is_i64(&self) -> bool
{
31 N
::PosInt(v
) => v
<= i64::MAX
as u64,
37 /// Returns `true` if the number can be represented as `u64`.
39 pub fn is_u64(&self) -> bool
{
42 N
::NegInt(_
) | N
::Float(_
) => false,
46 /// Returns `true` if the number can be represented as `f64`.
48 pub fn is_f64(&self) -> bool
{
51 N
::PosInt(_
) | N
::NegInt(_
) => false,
55 /// Returns the number represented as `i64` if possible, or else `None`.
57 pub fn as_i64(&self) -> Option
<i64> {
59 N
::PosInt(n
) => NumCast
::from(n
),
60 N
::NegInt(n
) => Some(n
),
65 /// Returns the number represented as `u64` if possible, or else `None`.
67 pub fn as_u64(&self) -> Option
<u64> {
69 N
::PosInt(n
) => Some(n
),
70 N
::NegInt(n
) => NumCast
::from(n
),
75 /// Returns the number represented as `f64` if possible, or else `None`.
77 pub fn as_f64(&self) -> Option
<f64> {
79 N
::PosInt(n
) => NumCast
::from(n
),
80 N
::NegInt(n
) => NumCast
::from(n
),
81 N
::Float(n
) => Some(n
),
85 /// Converts a finite `f64` to a `Number`. Infinite or NaN values are not JSON
88 pub fn from_f64(f
: f64) -> Option
<Number
> {
90 Some(Number { n: N::Float(f) }
)
97 impl fmt
::Display
for Number
{
98 fn fmt(&self, formatter
: &mut fmt
::Formatter
) -> fmt
::Result
{
100 N
::PosInt(i
) => Display
::fmt(&i
, formatter
),
101 N
::NegInt(i
) => Display
::fmt(&i
, formatter
),
102 N
::Float(f
) => Display
::fmt(&f
, formatter
),
107 impl Debug
for Number
{
108 fn fmt(&self, formatter
: &mut fmt
::Formatter
) -> fmt
::Result
{
109 Debug
::fmt(&self.n
, formatter
)
113 impl Serialize
for Number
{
115 fn serialize
<S
>(&self, serializer
: S
) -> Result
<S
::Ok
, S
::Error
>
119 N
::PosInt(i
) => serializer
.serialize_u64(i
),
120 N
::NegInt(i
) => serializer
.serialize_i64(i
),
121 N
::Float(f
) => serializer
.serialize_f64(f
),
126 impl Deserialize
for Number
{
128 fn deserialize
<D
>(deserializer
: D
) -> Result
<Number
, D
::Error
>
129 where D
: Deserializer
131 struct NumberVisitor
;
133 impl Visitor
for NumberVisitor
{
136 fn expecting(&self, formatter
: &mut fmt
::Formatter
) -> fmt
::Result
{
137 formatter
.write_str("a number")
141 fn visit_i64
<E
>(self, value
: i64) -> Result
<Number
, E
> {
146 fn visit_u64
<E
>(self, value
: u64) -> Result
<Number
, E
> {
151 fn visit_f64
<E
>(self, value
: f64) -> Result
<Number
, E
>
154 Number
::from_f64(value
).ok_or_else(|| de
::Error
::custom("not a JSON number"))
158 deserializer
.deserialize(NumberVisitor
)
162 impl Deserializer
for Number
{
166 fn deserialize
<V
>(self, visitor
: V
) -> Result
<V
::Value
, Error
>
170 N
::PosInt(i
) => visitor
.visit_u64(i
),
171 N
::NegInt(i
) => visitor
.visit_i64(i
),
172 N
::Float(f
) => visitor
.visit_f64(f
),
176 forward_to_deserialize
! {
177 bool
u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
178 seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct
179 tuple_struct
struct struct_field tuple
enum ignored_any
183 impl<'a
> Deserializer
for &'a Number
{
187 fn deserialize
<V
>(self, visitor
: V
) -> Result
<V
::Value
, Error
>
191 N
::PosInt(i
) => visitor
.visit_u64(i
),
192 N
::NegInt(i
) => visitor
.visit_i64(i
),
193 N
::Float(f
) => visitor
.visit_f64(f
),
197 forward_to_deserialize
! {
198 bool
u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
199 seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct
200 tuple_struct
struct struct_field tuple
enum ignored_any
204 macro_rules
! from_signed
{
205 ($
($signed_ty
:ident
)*) => {
207 impl From
<$signed_ty
> for Number
{
209 fn from(i
: $signed_ty
) -> Self {
211 Number { n: N::NegInt(i as i64) }
213 Number { n: N::PosInt(i as u64) }
221 macro_rules
! from_unsigned
{
222 ($
($unsigned_ty
:ident
)*) => {
224 impl From
<$unsigned_ty
> for Number
{
226 fn from(u
: $unsigned_ty
) -> Self {
227 Number { n: N::PosInt(u as u64) }
234 from_signed
!(i8 i16 i32 i64 isize);
235 from_unsigned
!(u8 u16 u32 u64 usize);