Browse Source

Turn the RequestIDProvider enum into a struct (#839)

Motivation:

Public enums are bad for API evolution. There's no reason the
RequestIDProvider can't be a struct instead.

Modifications:

- Turn RequestIDProvider into a struct

Result:

- Lower risk of API breakage
George Barnett 5 years ago
parent
commit
31a03ceca2

+ 28 - 13
Sources/GRPC/ClientOptions.swift

@@ -74,25 +74,40 @@ public struct CallOptions {
     self.cacheable = false
     self.cacheable = false
   }
   }
 
 
-  /// How Request IDs should be provided.
-  public enum RequestIDProvider {
-    /// Generate a new ID automatically.
-    case autogenerated
+  public struct RequestIDProvider {
+    private enum RequestIDSource {
+      case `static`(String)
+      case generated(() -> String)
+    }
+
+    private var source: RequestIDSource
+    private init(_ source: RequestIDSource) {
+      self.source = source
+    }
+
+    internal func requestID() -> String {
+      switch self.source {
+      case .static(let requestID):
+        return requestID
+      case .generated(let generator):
+        return generator()
+      }
+    }
+
+    /// Generate a new request ID for each RPC.
+    public static let autogenerated = RequestIDProvider(.generated({ UUID().uuidString }))
 
 
     /// Specify an ID to be used.
     /// Specify an ID to be used.
     ///
     ///
     /// - Important: this should only be used when `CallOptions` are passed directly to the call.
     /// - Important: this should only be used when `CallOptions` are passed directly to the call.
     ///   If it is used for the default options on a client then all calls with have the same ID.
     ///   If it is used for the default options on a client then all calls with have the same ID.
-    case userDefined(String)
-
-    func requestID() -> String {
-      switch self {
-      case .autogenerated:
-        return UUID().uuidString
+    public static func userDefined(_ requestID: String) -> RequestIDProvider {
+      return RequestIDProvider(.static(requestID))
+    }
 
 
-      case .userDefined(let id):
-        return id
-      }
+    /// Provide a factory to generate request IDs.
+    public static func generated(_ requestIDFactory: @escaping () -> String) -> RequestIDProvider {
+      return RequestIDProvider(.generated(requestIDFactory))
     }
     }
   }
   }
 }
 }

+ 37 - 0
Tests/GRPCTests/RequestIDProviderTests.swift

@@ -0,0 +1,37 @@
+/*
+ * Copyright 2020, gRPC Authors All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+@testable import GRPC
+import XCTest
+
+class RequestIDProviderTests: GRPCTestCase {
+  func testUserDefined() {
+    let provider = CallOptions.RequestIDProvider.userDefined("foo")
+    XCTAssertEqual(provider.requestID(), "foo")
+    XCTAssertEqual(provider.requestID(), "foo")
+  }
+
+  func testAutogenerated() {
+    let provider = CallOptions.RequestIDProvider.autogenerated
+    XCTAssertNotEqual(provider.requestID(), provider.requestID())
+  }
+
+  func testGenerator() {
+    let provider = CallOptions.RequestIDProvider.generated {
+      return "foo"
+    }
+    XCTAssertEqual(provider.requestID(), "foo")
+  }
+}

+ 12 - 0
Tests/GRPCTests/XCTestManifests.swift

@@ -614,6 +614,17 @@ extension ReadStateTests {
     ]
     ]
 }
 }
 
 
+extension RequestIDProviderTests {
+    // DO NOT MODIFY: This is autogenerated, use:
+    //   `swift test --generate-linuxmain`
+    // to regenerate.
+    static let __allTests__RequestIDProviderTests = [
+        ("testAutogenerated", testAutogenerated),
+        ("testGenerator", testGenerator),
+        ("testUserDefined", testUserDefined),
+    ]
+}
+
 extension ServerDelayedThrowingTests {
 extension ServerDelayedThrowingTests {
     // DO NOT MODIFY: This is autogenerated, use:
     // DO NOT MODIFY: This is autogenerated, use:
     //   `swift test --generate-linuxmain`
     //   `swift test --generate-linuxmain`
@@ -746,6 +757,7 @@ public func __allTests() -> [XCTestCaseEntry] {
         testCase(MessageEncodingHeaderValidatorTests.__allTests__MessageEncodingHeaderValidatorTests),
         testCase(MessageEncodingHeaderValidatorTests.__allTests__MessageEncodingHeaderValidatorTests),
         testCase(PlatformSupportTests.__allTests__PlatformSupportTests),
         testCase(PlatformSupportTests.__allTests__PlatformSupportTests),
         testCase(ReadStateTests.__allTests__ReadStateTests),
         testCase(ReadStateTests.__allTests__ReadStateTests),
+        testCase(RequestIDProviderTests.__allTests__RequestIDProviderTests),
         testCase(ServerDelayedThrowingTests.__allTests__ServerDelayedThrowingTests),
         testCase(ServerDelayedThrowingTests.__allTests__ServerDelayedThrowingTests),
         testCase(ServerErrorTransformingTests.__allTests__ServerErrorTransformingTests),
         testCase(ServerErrorTransformingTests.__allTests__ServerErrorTransformingTests),
         testCase(ServerTLSErrorTests.__allTests__ServerTLSErrorTests),
         testCase(ServerTLSErrorTests.__allTests__ServerTLSErrorTests),