diff --git a/Cargo.toml b/Cargo.toml index 4817ac7a1..a840f7915 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "serde_json" -version = "1.0.117" +version = "1.0.118" authors = ["Erick Tryzelaar ", "David Tolnay "] categories = ["encoding", "parser-implementations", "no-std"] description = "A JSON serialization file format" @@ -34,7 +34,7 @@ doc-scrape-examples = false [package.metadata.docs.rs] features = ["preserve_order", "raw_value", "unbounded_depth"] targets = ["x86_64-unknown-linux-gnu"] -rustdoc-args = ["--cfg", "docsrs", "--generate-link-to-definition"] +rustdoc-args = ["--generate-link-to-definition"] [package.metadata.playground] features = ["raw_value"] diff --git a/src/lexical/num.rs b/src/lexical/num.rs index 75eee01b8..3f3914021 100644 --- a/src/lexical/num.rs +++ b/src/lexical/num.rs @@ -206,8 +206,6 @@ pub trait Float: Number { // MASKS - /// Bitmask for the sign bit. - const SIGN_MASK: Self::Unsigned; /// Bitmask for the exponent, including the hidden bit. const EXPONENT_MASK: Self::Unsigned; /// Bitmask for the hidden bit in exponent, which is an implicit 1 in the fraction. @@ -219,8 +217,6 @@ pub trait Float: Number { /// Positive infinity as bits. const INFINITY_BITS: Self::Unsigned; - /// Positive infinity as bits. - const NEGATIVE_INFINITY_BITS: Self::Unsigned; /// Size of the significand (mantissa) without hidden bit. const MANTISSA_SIZE: i32; /// Bias of the exponent @@ -315,12 +311,10 @@ impl Float for f32 { const ZERO: f32 = 0.0; const MAX_DIGITS: usize = 114; - const SIGN_MASK: u32 = 0x80000000; const EXPONENT_MASK: u32 = 0x7F800000; const HIDDEN_BIT_MASK: u32 = 0x00800000; const MANTISSA_MASK: u32 = 0x007FFFFF; const INFINITY_BITS: u32 = 0x7F800000; - const NEGATIVE_INFINITY_BITS: u32 = Self::INFINITY_BITS | Self::SIGN_MASK; const MANTISSA_SIZE: i32 = 23; const EXPONENT_BIAS: i32 = 127 + Self::MANTISSA_SIZE; const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS; @@ -374,12 +368,10 @@ impl Float for f64 { const ZERO: f64 = 0.0; const MAX_DIGITS: usize = 769; - const SIGN_MASK: u64 = 0x8000000000000000; const EXPONENT_MASK: u64 = 0x7FF0000000000000; const HIDDEN_BIT_MASK: u64 = 0x0010000000000000; const MANTISSA_MASK: u64 = 0x000FFFFFFFFFFFFF; const INFINITY_BITS: u64 = 0x7FF0000000000000; - const NEGATIVE_INFINITY_BITS: u64 = Self::INFINITY_BITS | Self::SIGN_MASK; const MANTISSA_SIZE: i32 = 52; const EXPONENT_BIAS: i32 = 1023 + Self::MANTISSA_SIZE; const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS; diff --git a/src/lib.rs b/src/lib.rs index 475cd4475..9d4b6497a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -299,7 +299,7 @@ //! [macro]: crate::json //! [`serde-json-core`]: https://github.com/rust-embedded-community/serde-json-core -#![doc(html_root_url = "https://docs.rs/serde_json/1.0.117")] +#![doc(html_root_url = "https://docs.rs/serde_json/1.0.118")] // Ignored clippy lints #![allow( clippy::collapsible_else_if, diff --git a/src/map.rs b/src/map.rs index 520cd6cf5..d62513daf 100644 --- a/src/map.rs +++ b/src/map.rs @@ -8,9 +8,11 @@ use crate::value::Value; use alloc::string::String; +#[cfg(feature = "preserve_order")] +use alloc::vec::Vec; use core::borrow::Borrow; use core::fmt::{self, Debug}; -use core::hash::Hash; +use core::hash::{Hash, Hasher}; use core::iter::FusedIterator; #[cfg(feature = "preserve_order")] use core::mem; @@ -368,6 +370,22 @@ impl PartialEq for Map { impl Eq for Map {} +impl Hash for Map { + fn hash(&self, state: &mut H) { + #[cfg(not(feature = "preserve_order"))] + { + self.map.hash(state); + } + + #[cfg(feature = "preserve_order")] + { + let mut kv = Vec::from_iter(&self.map); + kv.sort_unstable_by(|a, b| a.0.cmp(b.0)); + kv.hash(state); + } + } +} + /// Access an element of this map. Panics if the given key is not present in the /// map. /// diff --git a/src/value/mod.rs b/src/value/mod.rs index b3f51ea0d..026f10dcb 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -112,7 +112,7 @@ pub use crate::raw::{to_raw_value, RawValue}; /// Represents any valid JSON value. /// /// See the [`serde_json::value` module documentation](self) for usage examples. -#[derive(Clone, Eq, PartialEq)] +#[derive(Clone, Eq, PartialEq, Hash)] pub enum Value { /// Represents a JSON null value. /// diff --git a/tests/compiletest.rs b/tests/compiletest.rs index 7974a6249..23a6a065e 100644 --- a/tests/compiletest.rs +++ b/tests/compiletest.rs @@ -1,5 +1,5 @@ -#[rustversion::attr(not(nightly), ignore)] -#[cfg_attr(miri, ignore)] +#[rustversion::attr(not(nightly), ignore = "requires nightly")] +#[cfg_attr(miri, ignore = "incompatible with miri")] #[test] fn ui() { let t = trybuild::TestCases::new(); diff --git a/tests/lexical/num.rs b/tests/lexical/num.rs index 1a94be013..e7d08652e 100644 --- a/tests/lexical/num.rs +++ b/tests/lexical/num.rs @@ -63,7 +63,6 @@ fn check_float(x: T) { assert!(T::from_bits(x.to_bits()) == x); // Check properties - let _ = x.to_bits() & T::SIGN_MASK; let _ = x.to_bits() & T::EXPONENT_MASK; let _ = x.to_bits() & T::HIDDEN_BIT_MASK; let _ = x.to_bits() & T::MANTISSA_MASK; diff --git a/tests/stream.rs b/tests/stream.rs index ec6b9e3d0..fa52cedeb 100644 --- a/tests/stream.rs +++ b/tests/stream.rs @@ -1,4 +1,3 @@ -#![cfg(not(feature = "preserve_order"))] #![allow(clippy::assertions_on_result_states)] use serde_json::{json, Deserializer, Value}; diff --git a/tests/test.rs b/tests/test.rs index 8c9af6b32..c18254a85 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -1,4 +1,3 @@ -#![cfg(not(feature = "preserve_order"))] #![allow( clippy::assertions_on_result_states, clippy::cast_precision_loss, @@ -7,6 +6,7 @@ clippy::float_cmp, clippy::incompatible_msrv, // https://github.com/rust-lang/rust-clippy/issues/12257 clippy::items_after_statements, + clippy::large_digit_groups, clippy::let_underscore_untyped, clippy::shadow_unrelated, clippy::too_many_lines, @@ -2311,9 +2311,9 @@ fn test_borrowed_raw_value() { let array_from_str: Vec<&RawValue> = serde_json::from_str(r#"["a", 42, {"foo": "bar"}, null]"#).unwrap(); assert_eq!(r#""a""#, array_from_str[0].get()); - assert_eq!(r#"42"#, array_from_str[1].get()); + assert_eq!("42", array_from_str[1].get()); assert_eq!(r#"{"foo": "bar"}"#, array_from_str[2].get()); - assert_eq!(r#"null"#, array_from_str[3].get()); + assert_eq!("null", array_from_str[3].get()); let array_to_string = serde_json::to_string(&array_from_str).unwrap(); assert_eq!(r#"["a",42,{"foo": "bar"},null]"#, array_to_string); @@ -2390,16 +2390,16 @@ fn test_boxed_raw_value() { let array_from_str: Vec> = serde_json::from_str(r#"["a", 42, {"foo": "bar"}, null]"#).unwrap(); assert_eq!(r#""a""#, array_from_str[0].get()); - assert_eq!(r#"42"#, array_from_str[1].get()); + assert_eq!("42", array_from_str[1].get()); assert_eq!(r#"{"foo": "bar"}"#, array_from_str[2].get()); - assert_eq!(r#"null"#, array_from_str[3].get()); + assert_eq!("null", array_from_str[3].get()); let array_from_reader: Vec> = serde_json::from_reader(br#"["a", 42, {"foo": "bar"}, null]"#.as_ref()).unwrap(); assert_eq!(r#""a""#, array_from_reader[0].get()); - assert_eq!(r#"42"#, array_from_reader[1].get()); + assert_eq!("42", array_from_reader[1].get()); assert_eq!(r#"{"foo": "bar"}"#, array_from_reader[2].get()); - assert_eq!(r#"null"#, array_from_reader[3].get()); + assert_eq!("null", array_from_reader[3].get()); let array_to_string = serde_json::to_string(&array_from_str).unwrap(); assert_eq!(r#"["a",42,{"foo": "bar"},null]"#, array_to_string);