diff --git a/build.rs b/build.rs index 04ff4a0..e9ec7d5 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#stabilized-apis + 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 716f128..f847c21 100644 --- a/src/map.rs +++ b/src/map.rs @@ -234,6 +234,19 @@ impl Map { } } + /// Retains only the elements specified by the predicate. + /// + /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` + /// returns `false`. + #[cfg(not(no_btreemap_retain))] + #[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 387a72c..ae01969 100644 --- a/tests/map.rs +++ b/tests/map.rs @@ -34,3 +34,14 @@ fn test_append() { assert_eq!(keys, EXPECTED); assert!(val.is_empty()); } + +#[cfg(not(no_btreemap_retain))] +#[test] +fn test_retain() { + 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, &["a", "c"]); +}