Skip to content

Commit

Permalink
Add swap_remove and shift_remove methods on Map
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Jan 29, 2024
1 parent 7fece96 commit ca3c2ca
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 4 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ repository = "https://github.com/serde-rs/json"
rust-version = "1.56"

[dependencies]
indexmap = { version = "2", optional = true }
indexmap = { version = "2.2.1", optional = true }
itoa = "1.0"
ryu = "1.0"
serde = { version = "1.0.194", default-features = false }
Expand All @@ -32,7 +32,7 @@ trybuild = { version = "1.0.81", features = ["diff"] }
doc-scrape-examples = false

[package.metadata.docs.rs]
features = ["raw_value", "unbounded_depth"]
features = ["preserve_order", "raw_value", "unbounded_depth"]
targets = ["x86_64-unknown-linux-gnu"]
rustdoc-args = ["--cfg", "docsrs", "--generate-link-to-definition"]

Expand Down
84 changes: 82 additions & 2 deletions src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,20 @@ impl Map<String, Value> {
///
/// The key may be any borrowed form of the map's key type, but the ordering
/// on the borrowed form *must* match the ordering on the key type.
///
/// If serde_json's "preserve_order" is enabled, `.remove(key)` is
/// equivalent to [`.swap_remove(key)`][Self::swap_remove], replacing this
/// entry's position with the last element. If you need to preserve the
/// relative order of the keys in the map, use
/// [`.shift_remove(key)`][Self::shift_remove] instead.
#[inline]
pub fn remove<Q>(&mut self, key: &Q) -> Option<Value>
where
String: Borrow<Q>,
Q: ?Sized + Ord + Eq + Hash,
{
#[cfg(feature = "preserve_order")]
return self.map.swap_remove(key);
return self.swap_remove(key);
#[cfg(not(feature = "preserve_order"))]
return self.map.remove(key);
}
Expand All @@ -147,12 +153,86 @@ impl Map<String, Value> {
///
/// The key may be any borrowed form of the map's key type, but the ordering
/// on the borrowed form *must* match the ordering on the key type.
///
/// If serde_json's "preserve_order" is enabled, `.remove_entry(key)` is
/// equivalent to [`.swap_remove_entry(key)`][Self::swap_remove_entry],
/// replacing this entry's position with the last element. If you need to
/// preserve the relative order of the keys in the map, use
/// [`.shift_remove_entry(key)`][Self::shift_remove_entry] instead.
#[inline]
pub fn remove_entry<Q>(&mut self, key: &Q) -> Option<(String, Value)>
where
String: Borrow<Q>,
Q: ?Sized + Ord + Eq + Hash,
{
self.map.remove_entry(key)
#[cfg(feature = "preserve_order")]
return self.swap_remove_entry(key);
#[cfg(not(feature = "preserve_order"))]
return self.map.remove_entry(key);
}

/// Removes and returns the value corresponding to the key from the map.
///
/// Like [`Vec::swap_remove`], the entry is removed by swapping it with the
/// last element of the map and popping it off. This perturbs the position
/// of what used to be the last element!
#[cfg(feature = "preserve_order")]
#[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))]
#[inline]
pub fn swap_remove<Q>(&mut self, key: &Q) -> Option<Value>
where
String: Borrow<Q>,
Q: ?Sized + Ord + Eq + Hash,
{
self.map.swap_remove(key)
}

/// Remove and return the key-value pair.
///
/// Like [`Vec::swap_remove`], the entry is removed by swapping it with the
/// last element of the map and popping it off. This perturbs the position
/// of what used to be the last element!
#[cfg(feature = "preserve_order")]
#[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))]
#[inline]
pub fn swap_remove_entry<Q>(&mut self, key: &Q) -> Option<(String, Value)>
where
String: Borrow<Q>,
Q: ?Sized + Ord + Eq + Hash,
{
self.map.swap_remove_entry(key)
}

/// Removes and returns the value corresponding to the key from the map.
///
/// Like [`Vec::remove`], the entry is removed by shifting all of the
/// elements that follow it, preserving their relative order. This perturbs
/// the index of all of those elements!
#[cfg(feature = "preserve_order")]
#[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))]
#[inline]
pub fn shift_remove<Q>(&mut self, key: &Q) -> Option<Value>
where
String: Borrow<Q>,
Q: ?Sized + Ord + Eq + Hash,
{
self.map.shift_remove(key)
}

/// Remove and return the key-value pair.
///
/// Like [`Vec::remove`], the entry is removed by shifting all of the
/// elements that follow it, preserving their relative order. This perturbs
/// the index of all of those elements!
#[cfg(feature = "preserve_order")]
#[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))]
#[inline]
pub fn shift_remove_entry<Q>(&mut self, key: &Q) -> Option<(String, Value)>
where
String: Borrow<Q>,
Q: ?Sized + Ord + Eq + Hash,
{
self.map.shift_remove_entry(key)
}

/// Moves all elements from other into self, leaving other empty.
Expand Down

0 comments on commit ca3c2ca

Please sign in to comment.