Browse Source

Add `removeAll(where:)` to `Metadata`. (#1869)

Motivation:

Sometimes users want to remove some values from `Metadata`. At the moment they can only remove one at a time or all values.

Modifications:

Add `removeAll(where:)` to `Metadata`.

Result:

Users can now remove values from `Metadata` that match a given predicate.
Clinton Nkwocha 1 year ago
parent
commit
8bc72fd0c0
2 changed files with 35 additions and 0 deletions
  1. 13 0
      Sources/GRPCCore/Metadata.swift
  2. 22 0
      Tests/GRPCCoreTests/MetadataTests.swift

+ 13 - 0
Sources/GRPCCore/Metadata.swift

@@ -226,6 +226,19 @@ public struct Metadata: Sendable, Hashable {
   public mutating func removeAll(keepingCapacity: Bool) {
     self.elements.removeAll(keepingCapacity: keepingCapacity)
   }
+
+  /// Removes all elements which match the given predicate.
+  ///
+  /// - Parameter predicate: Returns `true` if the element should be removed.
+  ///
+  /// - Complexity: O(*n*), where *n* is the number of entries in the metadata instance.
+  public mutating func removeAll(
+    where predicate: (_ key: String, _ value: Value) throws -> Bool
+  ) rethrows {
+    try self.elements.removeAll { pair in
+      try predicate(pair.key, pair.value)
+    }
+  }
 }
 
 extension Metadata: RandomAccessCollection {

+ 22 - 0
Tests/GRPCCoreTests/MetadataTests.swift

@@ -205,4 +205,26 @@ final class MetadataTests: XCTestCase {
     XCTAssertEqual(stringIterator.next(), "value2")
     XCTAssertNil(stringIterator.next())
   }
+
+  func testRemoveAllWhere() {
+    let metadata: Metadata = [
+      "testKey1": "value1",
+      "testKey2": "value2",
+      "testKey3": "value1",
+    ]
+
+    var metadata1 = metadata
+    metadata1.removeAll { _, value in
+      value == "value1"
+    }
+
+    XCTAssertEqual(metadata1, ["testKey2": "value2"])
+
+    var metadata2 = metadata
+    metadata2.removeAll { key, _ in
+      key == "testKey2"
+    }
+
+    XCTAssertEqual(metadata2, ["testKey1": "value1", "testKey3": "value1"])
+  }
 }