use crate::de::ParserNumber;
use crate::error::Error;
-use crate::lib::*;
+#[cfg(feature = "arbitrary_precision")]
+use crate::error::ErrorCode;
+#[cfg(feature = "arbitrary_precision")]
+use alloc::borrow::ToOwned;
+#[cfg(feature = "arbitrary_precision")]
+use alloc::string::{String, ToString};
+use core::fmt::{self, Debug, Display};
+#[cfg(not(feature = "arbitrary_precision"))]
+use core::hash::{Hash, Hasher};
use serde::de::{self, Unexpected, Visitor};
+#[cfg(feature = "arbitrary_precision")]
+use serde::de::{IntoDeserializer, MapAccess};
use serde::{
forward_to_deserialize_any, serde_if_integer128, Deserialize, Deserializer, Serialize,
Serializer,
};
-#[cfg(feature = "arbitrary_precision")]
-use crate::error::ErrorCode;
-#[cfg(feature = "arbitrary_precision")]
-use serde::de::{IntoDeserializer, MapAccess};
-
#[cfg(feature = "arbitrary_precision")]
pub(crate) const TOKEN: &str = "$serde_json::private::Number";
/// Represents a JSON number, whether integer or floating point.
-#[derive(Clone, Eq, PartialEq)]
+#[derive(Clone, PartialEq, Eq, Hash)]
pub struct Number {
n: N,
}
#[cfg(not(feature = "arbitrary_precision"))]
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone)]
enum N {
PosInt(u64),
/// Always less than zero.
Float(f64),
}
+#[cfg(not(feature = "arbitrary_precision"))]
+impl PartialEq for N {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (N::PosInt(a), N::PosInt(b)) => a == b,
+ (N::NegInt(a), N::NegInt(b)) => a == b,
+ (N::Float(a), N::Float(b)) => a == b,
+ _ => false,
+ }
+ }
+}
+
// Implementing Eq is fine since any float values are always finite.
#[cfg(not(feature = "arbitrary_precision"))]
impl Eq for N {}
+#[cfg(not(feature = "arbitrary_precision"))]
+impl Hash for N {
+ fn hash<H: Hasher>(&self, h: &mut H) {
+ match *self {
+ N::PosInt(i) => i.hash(h),
+ N::NegInt(i) => i.hash(h),
+ N::Float(f) => {
+ if f == 0.0f64 {
+ // There are 2 zero representations, +0 and -0, which
+ // compare equal but have different bits. We use the +0 hash
+ // for both so that hash(+0) == hash(-0).
+ 0.0f64.to_bits().hash(h);
+ } else {
+ f.to_bits().hash(h);
+ }
+ }
+ }
+ }
+}
+
#[cfg(feature = "arbitrary_precision")]
type N = String;
{
for c in self.n.chars() {
if c == '.' || c == 'e' || c == 'E' {
- return self.n.parse::<f64>().ok().map_or(false, |f| f.is_finite());
+ return self.n.parse::<f64>().ok().map_or(false, f64::is_finite);
}
}
false
}
}
-impl fmt::Display for Number {
+impl Display for Number {
#[cfg(not(feature = "arbitrary_precision"))]
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
match self.n {
- N::PosInt(u) => Display::fmt(&u, formatter),
- N::NegInt(i) => Display::fmt(&i, formatter),
- N::Float(f) => Display::fmt(&f, formatter),
+ N::PosInt(u) => formatter.write_str(itoa::Buffer::new().format(u)),
+ N::NegInt(i) => formatter.write_str(itoa::Buffer::new().format(i)),
+ N::Float(f) => formatter.write_str(ryu::Buffer::new().format_finite(f)),
}
}
}
impl Debug for Number {
- #[cfg(not(feature = "arbitrary_precision"))]
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- let mut debug = formatter.debug_tuple("Number");
- match self.n {
- N::PosInt(i) => {
- debug.field(&i);
- }
- N::NegInt(i) => {
- debug.field(&i);
- }
- N::Float(f) => {
- debug.field(&f);
- }
- }
- debug.finish()
- }
-
- #[cfg(feature = "arbitrary_precision")]
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter
- .debug_tuple("Number")
- .field(&format_args!("{}", self.n))
- .finish()
+ write!(formatter, "Number({})", self)
}
}
serde_if_integer128! {
impl From<i128> for Number {
fn from(i: i128) -> Self {
- Number { n: i.to_string() }
+ let n = itoa::Buffer::new().format(i).to_owned();
+ Number { n }
}
}
impl From<u128> for Number {
fn from(u: u128) -> Self {
- Number { n: u.to_string() }
+ let n = itoa::Buffer::new().format(u).to_owned();
+ Number { n }
}
}
}