Skip to content
This repository has been archived by the owner on Mar 25, 2024. It is now read-only.

Commit

Permalink
Add swap_remove and shift_remove methods on Mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Jan 29, 2024
1 parent 8b26413 commit f8a99a4
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 21 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ repository = "https://github.com/dtolnay/serde-yaml"
rust-version = "1.64"

[dependencies]
indexmap = "2"
indexmap = "2.2.1"
itoa = "1.0"
ryu = "1.0"
serde = "1.0.195"
Expand Down
120 changes: 100 additions & 20 deletions src/mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,65 @@ impl Mapping {
}

/// Removes and returns the value corresponding to the key from the map.
///
/// This is equivalent to [`.swap_remove(index)`][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<I: Index>(&mut self, index: I) -> Option<Value> {
index.remove_from(self)
self.swap_remove(index)
}

/// Remove and return the key-value pair.
///
/// This is equivalent to [`.swap_remove_entry(index)`][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<I: Index>(&mut self, index: I) -> Option<(Value, Value)> {
index.remove_entry_from(self)
self.swap_remove_entry(index)
}

/// 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!
#[inline]
pub fn swap_remove<I: Index>(&mut self, index: I) -> Option<Value> {
index.swap_remove_from(self)
}

/// 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!
#[inline]
pub fn swap_remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)> {
index.swap_remove_entry_from(self)
}

/// 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!
#[inline]
pub fn shift_remove<I: Index>(&mut self, index: I) -> Option<Value> {
index.shift_remove_from(self)
}

/// 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!
#[inline]
pub fn shift_remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)> {
index.shift_remove_entry_from(self)
}

/// Scan through each key-value pair in the map and keep those where the
Expand Down Expand Up @@ -203,10 +253,16 @@ pub trait Index: private::Sealed {
fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value>;

#[doc(hidden)]
fn remove_from(&self, v: &mut Mapping) -> Option<Value>;
fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value>;

#[doc(hidden)]
fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>;

#[doc(hidden)]
fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value>;

#[doc(hidden)]
fn remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>;
fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>;
}

struct HashLikeValue<'a>(&'a str);
Expand Down Expand Up @@ -239,11 +295,17 @@ impl Index for Value {
fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
v.map.get_mut(self)
}
fn remove_from(&self, v: &mut Mapping) -> Option<Value> {
v.map.remove(self)
fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
v.map.swap_remove(self)
}
fn remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
v.map.remove_entry(self)
fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
v.map.swap_remove_entry(self)
}
fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
v.map.shift_remove(self)
}
fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
v.map.shift_remove_entry(self)
}
}

Expand All @@ -257,11 +319,17 @@ impl Index for str {
fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
v.map.get_mut(&HashLikeValue(self))
}
fn remove_from(&self, v: &mut Mapping) -> Option<Value> {
v.map.remove(&HashLikeValue(self))
fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
v.map.swap_remove(&HashLikeValue(self))
}
fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
v.map.swap_remove_entry(&HashLikeValue(self))
}
fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
v.map.shift_remove(&HashLikeValue(self))
}
fn remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
v.map.remove_entry(&HashLikeValue(self))
fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
v.map.shift_remove_entry(&HashLikeValue(self))
}
}

Expand All @@ -275,11 +343,17 @@ impl Index for String {
fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
self.as_str().index_into_mut(v)
}
fn remove_from(&self, v: &mut Mapping) -> Option<Value> {
self.as_str().remove_from(v)
fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
self.as_str().swap_remove_from(v)
}
fn remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
self.as_str().remove_entry_from(v)
fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
self.as_str().swap_remove_entry_from(v)
}
fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
self.as_str().shift_remove_from(v)
}
fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
self.as_str().shift_remove_entry_from(v)
}
}

Expand All @@ -296,11 +370,17 @@ where
fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
(**self).index_into_mut(v)
}
fn remove_from(&self, v: &mut Mapping) -> Option<Value> {
(**self).remove_from(v)
fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
(**self).swap_remove_from(v)
}
fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
(**self).swap_remove_entry_from(v)
}
fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
(**self).shift_remove_from(v)
}
fn remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
(**self).remove_entry_from(v)
fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
(**self).shift_remove_entry_from(v)
}
}

Expand Down

0 comments on commit f8a99a4

Please sign in to comment.