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

Add swap_remove and shift_remove methods on Mapping #408

Merged
merged 1 commit into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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