Skip to content

Commit

Permalink
Add support to preserve_order in no_std
Browse files Browse the repository at this point in the history
  • Loading branch information
yukibtc committed Jan 5, 2024
1 parent 0131ac6 commit a32edef
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 8 deletions.
7 changes: 4 additions & 3 deletions Cargo.toml
Expand Up @@ -12,7 +12,8 @@ repository = "https://github.com/serde-rs/json"
rust-version = "1.56"

[dependencies]
indexmap = { version = "2", optional = true }
ahash = { version = "0.8", default-features = false, optional = true }
indexmap = { version = "2", default-features = false, optional = true }
itoa = "1.0"
ryu = "1.0"
serde = { version = "1.0.194", default-features = false }
Expand Down Expand Up @@ -45,7 +46,7 @@ features = ["raw_value"]
[features]
default = ["std"]

std = ["serde/std"]
std = ["serde/std", "ahash?/std", "indexmap?/std"]

# Provide integration for heap-allocated collections without depending on the
# rest of the Rust standard library.
Expand All @@ -55,7 +56,7 @@ alloc = ["serde/alloc"]
# Make serde_json::Map use a representation which maintains insertion order.
# This allows data to be read into a Value and written back to a JSON string
# while preserving the order of map keys in the input.
preserve_order = ["indexmap", "std"]
preserve_order = ["ahash", "indexmap"]

# Use sufficient precision when parsing fixed precision floats from JSON to
# ensure that they maintain accuracy when round-tripped through JSON. This comes
Expand Down
28 changes: 23 additions & 5 deletions src/map.rs
Expand Up @@ -7,6 +7,8 @@
//! [`IndexMap`]: https://docs.rs/indexmap/*/indexmap/map/struct.IndexMap.html

use crate::value::Value;
#[cfg(feature = "preserve_order")]
use ahash::RandomState;
use alloc::string::String;
use core::borrow::Borrow;
use core::fmt::{self, Debug};
Expand All @@ -30,14 +32,17 @@ pub struct Map<K, V> {
#[cfg(not(feature = "preserve_order"))]
type MapImpl<K, V> = BTreeMap<K, V>;
#[cfg(feature = "preserve_order")]
type MapImpl<K, V> = IndexMap<K, V>;
type MapImpl<K, V> = IndexMap<K, V, RandomState>;

impl Map<String, Value> {
/// Makes a new empty Map.
#[inline]
pub fn new() -> Self {
Map {
#[cfg(not(feature = "preserve_order"))]
map: MapImpl::new(),
#[cfg(feature = "preserve_order")]
map: MapImpl::with_hasher(RandomState::new()),
}
}

Expand All @@ -52,7 +57,7 @@ impl Map<String, Value> {
BTreeMap::new()
},
#[cfg(feature = "preserve_order")]
map: IndexMap::with_capacity(capacity),
map: IndexMap::with_capacity_and_hasher(capacity, RandomState::new()),
}
}

Expand Down Expand Up @@ -159,8 +164,10 @@ impl Map<String, Value> {
#[inline]
pub fn append(&mut self, other: &mut Self) {
#[cfg(feature = "preserve_order")]
self.map
.extend(mem::replace(&mut other.map, MapImpl::default()));
self.map.extend(mem::replace(
&mut other.map,
MapImpl::with_hasher(RandomState::new()),
));
#[cfg(not(feature = "preserve_order"))]
self.map.append(&mut other.map);
}
Expand Down Expand Up @@ -252,7 +259,10 @@ impl Default for Map<String, Value> {
#[inline]
fn default() -> Self {
Map {
#[cfg(not(feature = "preserve_order"))]
map: MapImpl::new(),
#[cfg(feature = "preserve_order")]
map: MapImpl::with_hasher(RandomState::new()),
}
}
}
Expand Down Expand Up @@ -400,8 +410,16 @@ impl FromIterator<(String, Value)> for Map<String, Value> {
where
T: IntoIterator<Item = (String, Value)>,
{
Map {
Self {
#[cfg(not(feature = "preserve_order"))]
map: FromIterator::from_iter(iter),
#[cfg(feature = "preserve_order")]
map: {
// TODO: replace with `iter.into_iter().collect();` when RandomState will impl Default
let mut map = MapImpl::with_hasher(RandomState::new());
map.extend(iter);
map
},
}
}
}
Expand Down

0 comments on commit a32edef

Please sign in to comment.