From d275e04a772ad452f3a59b8f32952a5fc35e1b40 Mon Sep 17 00:00:00 2001 From: Dean Karn Date: Thu, 11 Nov 2021 20:24:37 -0800 Subject: [PATCH 1/8] Add retain to Map This adds the `retain` function to the Map type which calls the inner maps, Either indexmap or std BTreeMap's, retain. I'm trying to mutate a Value::Object's Map in-place and could't find a nice way without the retain function. --- src/map.rs | 26 ++++++++++++++++++++++++++ tests/map.rs | 12 ++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/map.rs b/src/map.rs index 716f12852..4613cc89d 100644 --- a/src/map.rs +++ b/src/map.rs @@ -234,6 +234,32 @@ impl Map { } } + #[cfg(feature = "preserve_order")] + /// Retains only the elements specified by the predicate. + /// + /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`. + /// The elements are visited in ascending key order. + #[inline] + pub fn retain(&mut self, f: F) + where + F: FnMut(&String, &mut Value) -> bool, + { + self.map.retain(f); + } + + #[cfg(not(feature = "preserve_order"))] + /// Retains only the elements specified by the predicate. + /// + /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`. + /// The elements are visited in ascending key order. + #[inline] + pub fn retain(&mut self, f: F) + where + F: FnMut(&String, &mut Value) -> bool, + { + self.map.retain(f); + } + /// Gets an iterator over the values of the map. #[inline] pub fn values(&self) -> Values { diff --git a/tests/map.rs b/tests/map.rs index 387a72cdd..3abdf3ec4 100644 --- a/tests/map.rs +++ b/tests/map.rs @@ -34,3 +34,15 @@ fn test_append() { assert_eq!(keys, EXPECTED); assert!(val.is_empty()); } + +#[test] +fn test_retain() { + const EXPECTED: &[&str] = &["a", "c"]; + + let mut v: Value = from_str(r#"{"b":null,"a":null,"c":null}"#).unwrap(); + let val = v.as_object_mut().unwrap(); + val.retain(|k, _| k.as_str() != "b"); + + let keys: Vec<_> = val.keys().collect(); + assert_eq!(keys, EXPECTED); +} From 0992b447213a33abde2765476feaf033996593f4 Mon Sep 17 00:00:00 2001 From: Dean Karn Date: Thu, 11 Nov 2021 21:19:51 -0800 Subject: [PATCH 2/8] only include retain for BTreeMap if Rust 1.53.0+ --- build.rs | 6 ++++++ src/map.rs | 2 +- tests/map.rs | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/build.rs b/build.rs index 04ff4a0a1..7f10111d7 100644 --- a/build.rs +++ b/build.rs @@ -31,6 +31,12 @@ fn main() { if minor < 45 { println!("cargo:rustc-cfg=no_btreemap_remove_entry"); } + + // BTreeMap::retain + // https://blog.rust-lang.org/2021/06/17/Rust-1.53.0.html#library-changes + if minor < 53 { + println!("cargo:rustc-cfg=no_btreemap_retain"); + } } fn rustc_minor_version() -> Option { diff --git a/src/map.rs b/src/map.rs index 4613cc89d..14b5b29c8 100644 --- a/src/map.rs +++ b/src/map.rs @@ -234,7 +234,7 @@ impl Map { } } - #[cfg(feature = "preserve_order")] + #[cfg(all(feature = "preserve_order", not(no_btreemap_remove_entry)))] /// Retains only the elements specified by the predicate. /// /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`. diff --git a/tests/map.rs b/tests/map.rs index 3abdf3ec4..adf00623f 100644 --- a/tests/map.rs +++ b/tests/map.rs @@ -35,6 +35,7 @@ fn test_append() { assert!(val.is_empty()); } +#[cfg(not(no_btreemap_retain))] #[test] fn test_retain() { const EXPECTED: &[&str] = &["a", "c"]; From 09c589243374d8eb10c885031c0f6ff29ac377e0 Mon Sep 17 00:00:00 2001 From: Dean Karn Date: Thu, 11 Nov 2021 21:29:42 -0800 Subject: [PATCH 3/8] test order --- src/map.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/map.rs b/src/map.rs index 14b5b29c8..b150908a1 100644 --- a/src/map.rs +++ b/src/map.rs @@ -234,12 +234,12 @@ impl Map { } } - #[cfg(all(feature = "preserve_order", not(no_btreemap_remove_entry)))] /// Retains only the elements specified by the predicate. /// /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`. /// The elements are visited in ascending key order. #[inline] + #[cfg(all(feature = "preserve_order", not(no_btreemap_remove_entry)))] pub fn retain(&mut self, f: F) where F: FnMut(&String, &mut Value) -> bool, @@ -247,12 +247,12 @@ impl Map { self.map.retain(f); } - #[cfg(not(feature = "preserve_order"))] /// Retains only the elements specified by the predicate. /// /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`. /// The elements are visited in ascending key order. #[inline] + #[cfg(not(feature = "preserve_order"))] pub fn retain(&mut self, f: F) where F: FnMut(&String, &mut Value) -> bool, From eaa1a319c0a4712d3e8669775dd4880efbcfbcdf Mon Sep 17 00:00:00 2001 From: Dean Karn Date: Thu, 11 Nov 2021 21:36:52 -0800 Subject: [PATCH 4/8] fix no_btreemap_retain name --- src/map.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/map.rs b/src/map.rs index b150908a1..739643fb2 100644 --- a/src/map.rs +++ b/src/map.rs @@ -234,12 +234,12 @@ impl Map { } } + #[cfg(all(feature = "preserve_order", not(no_btreemap_retain)))] /// Retains only the elements specified by the predicate. /// /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`. /// The elements are visited in ascending key order. #[inline] - #[cfg(all(feature = "preserve_order", not(no_btreemap_remove_entry)))] pub fn retain(&mut self, f: F) where F: FnMut(&String, &mut Value) -> bool, @@ -247,12 +247,12 @@ impl Map { self.map.retain(f); } + #[cfg(not(feature = "preserve_order"))] /// Retains only the elements specified by the predicate. /// /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`. /// The elements are visited in ascending key order. #[inline] - #[cfg(not(feature = "preserve_order"))] pub fn retain(&mut self, f: F) where F: FnMut(&String, &mut Value) -> bool, From 29a58a3077456600da25ab079476f1248ed9d6d3 Mon Sep 17 00:00:00 2001 From: Dean Karn Date: Thu, 11 Nov 2021 21:54:09 -0800 Subject: [PATCH 5/8] don't include indexmap retain without BTreeMap retain --- src/map.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/map.rs b/src/map.rs index 739643fb2..665102b00 100644 --- a/src/map.rs +++ b/src/map.rs @@ -247,7 +247,7 @@ impl Map { self.map.retain(f); } - #[cfg(not(feature = "preserve_order"))] + #[cfg(all(not(feature = "preserve_order"), not(no_btreemap_retain)))] /// Retains only the elements specified by the predicate. /// /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`. From 68d3b45c9766f8a36b278eabc870e8232128f83d Mon Sep 17 00:00:00 2001 From: Dean Karn Date: Thu, 11 Nov 2021 22:00:21 -0800 Subject: [PATCH 6/8] fix function signature --- src/map.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/map.rs b/src/map.rs index 665102b00..a6bdb6af3 100644 --- a/src/map.rs +++ b/src/map.rs @@ -240,7 +240,7 @@ impl Map { /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`. /// The elements are visited in ascending key order. #[inline] - pub fn retain(&mut self, f: F) + pub fn retain(&mut self, f: F) where F: FnMut(&String, &mut Value) -> bool, { From 9e36f611dbc37498a89fcbf43e01b2a9a2312c18 Mon Sep 17 00:00:00 2001 From: Dean Karn Date: Fri, 12 Nov 2021 18:49:45 -0800 Subject: [PATCH 7/8] Update build.rs Co-authored-by: David Tolnay --- build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.rs b/build.rs index 7f10111d7..e9ec7d56a 100644 --- a/build.rs +++ b/build.rs @@ -33,7 +33,7 @@ fn main() { } // BTreeMap::retain - // https://blog.rust-lang.org/2021/06/17/Rust-1.53.0.html#library-changes + // https://blog.rust-lang.org/2021/06/17/Rust-1.53.0.html#stabilized-apis if minor < 53 { println!("cargo:rustc-cfg=no_btreemap_retain"); } From debd7d07fc7bfb064b8a704cd9ef2f6f207f66db Mon Sep 17 00:00:00 2001 From: Dean Karn Date: Fri, 12 Nov 2021 18:58:00 -0800 Subject: [PATCH 8/8] remove duplicate function --- src/map.rs | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/map.rs b/src/map.rs index a6bdb6af3..5ab4a39c6 100644 --- a/src/map.rs +++ b/src/map.rs @@ -234,20 +234,7 @@ impl Map { } } - #[cfg(all(feature = "preserve_order", not(no_btreemap_retain)))] - /// Retains only the elements specified by the predicate. - /// - /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`. - /// The elements are visited in ascending key order. - #[inline] - pub fn retain(&mut self, f: F) - where - F: FnMut(&String, &mut Value) -> bool, - { - self.map.retain(f); - } - - #[cfg(all(not(feature = "preserve_order"), not(no_btreemap_retain)))] + #[cfg(not(no_btreemap_retain))] /// Retains only the elements specified by the predicate. /// /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`.