|
15 | 15 | */
|
16 | 16 |
|
17 | 17 | /// A `ServerInterceptorOperation` describes to which RPCs a server interceptor should be applied.
|
18 |
| -/// |
| 18 | +/// |
19 | 19 | /// You can configure a server interceptor to be applied to:
|
20 | 20 | /// - all RPCs and services;
|
21 | 21 | /// - requests directed only to specific services registered with your server; or
|
22 | 22 | /// - requests directed only to specific methods (of a specific service).
|
23 |
| -/// |
| 23 | +/// |
24 | 24 | /// - SeeAlso: ``ServerInterceptor`` for more information on server interceptors, and
|
25 | 25 | /// ``ClientInterceptorOperation`` for the client-side version of this type.
|
26 | 26 | public struct ServerInterceptorOperation: Sendable {
|
27 |
| - internal enum Wrapped: Sendable { |
28 |
| - case allServices(interceptor: any ServerInterceptor) |
29 |
| - case serviceSpecific(interceptor: any ServerInterceptor, services: [String]) |
30 |
| - case methodSpecific(interceptor: any ServerInterceptor, methods: [MethodDescriptor]) |
31 |
| - } |
| 27 | + /// The subject of a ``ServerInterceptorOperation``. |
| 28 | + /// The subject of an interceptor can either be all services and methods, only specific services, or only specific methods. |
| 29 | + public struct Subject: Sendable { |
| 30 | + internal enum Wrapped: Sendable { |
| 31 | + case all |
| 32 | + case services([ServiceDescriptor]) |
| 33 | + case methods([MethodDescriptor]) |
| 34 | + } |
32 | 35 |
|
33 |
| - /// An operation specifying an interceptor that applies to all RPCs across all services will be registered with this server. |
34 |
| - /// - Parameter interceptor: The interceptor to register with the server. |
35 |
| - /// - Returns: A ``ServerInterceptorOperation``. |
36 |
| - public static func applyToAllServices( |
37 |
| - _ interceptor: any ServerInterceptor |
38 |
| - ) -> Self { |
39 |
| - Self(wrapped: .allServices(interceptor: interceptor)) |
40 |
| - } |
| 36 | + private let wrapped: Wrapped |
41 | 37 |
|
42 |
| - /// An operation specifying an interceptor that will be applied only to RPCs directed to the specified services. |
43 |
| - /// - Parameters: |
44 |
| - /// - interceptor: The interceptor to register with the server. |
45 |
| - /// - services: The list of service names for which this interceptor should intercept RPCs. |
46 |
| - /// - Returns: A ``ServerInterceptorOperation``. |
47 |
| - public static func apply( |
48 |
| - _ interceptor: any ServerInterceptor, |
49 |
| - onlyToServices services: [String] |
50 |
| - ) -> Self { |
51 |
| - Self( |
52 |
| - wrapped: .serviceSpecific( |
53 |
| - interceptor: interceptor, |
54 |
| - services: services |
55 |
| - ) |
56 |
| - ) |
57 |
| - } |
| 38 | + /// An operation subject specifying an interceptor that applies to all RPCs across all services will be registered with this server. |
| 39 | + public static var all: Self { .init(wrapped: .all) } |
58 | 40 |
|
59 |
| - /// An operation specifying an interceptor that will be applied only to RPCs directed to the specified service methods. |
60 |
| - /// - Parameters: |
61 |
| - /// - interceptor: The interceptor to register with the server. |
62 |
| - /// - services: The list of method descriptors for which this interceptor should intercept RPCs. |
63 |
| - /// - Returns: A ``ServerInterceptorOperation``. |
64 |
| - public static func apply( |
65 |
| - _ interceptor: any ServerInterceptor, |
66 |
| - onlyToMethods methods: [MethodDescriptor] |
67 |
| - ) -> Self { |
68 |
| - Self( |
69 |
| - wrapped: .methodSpecific( |
70 |
| - interceptor: interceptor, |
71 |
| - methods: methods |
72 |
| - ) |
73 |
| - ) |
| 41 | + /// An operation subject specifying an interceptor that will be applied only to RPCs directed to the specified services. |
| 42 | + /// - Parameters: |
| 43 | + /// - services: The list of service names for which this interceptor should intercept RPCs. |
| 44 | + /// - Returns: A ``ServerInterceptorOperation``. |
| 45 | + public static func services(_ services: [ServiceDescriptor]) -> Self { |
| 46 | + Self(wrapped: .services(services)) |
| 47 | + } |
| 48 | + |
| 49 | + /// An operation subject specifying an interceptor that will be applied only to RPCs directed to the specified service methods. |
| 50 | + /// - Parameters: |
| 51 | + /// - methods: The list of method descriptors for which this interceptor should intercept RPCs. |
| 52 | + /// - Returns: A ``ServerInterceptorOperation``. |
| 53 | + public static func methods(_ methods: [MethodDescriptor]) -> Self { |
| 54 | + Self(wrapped: .methods(methods)) |
| 55 | + } |
| 56 | + |
| 57 | + internal func applies(to descriptor: MethodDescriptor) -> Bool { |
| 58 | + switch self.wrapped { |
| 59 | + case .all: |
| 60 | + return true |
| 61 | + |
| 62 | + case .services(let services): |
| 63 | + return services.map({ $0.fullyQualifiedService }).contains(descriptor.service) |
| 64 | + |
| 65 | + case .methods(let methods): |
| 66 | + return methods.contains(descriptor) |
| 67 | + } |
| 68 | + } |
74 | 69 | }
|
75 | 70 |
|
76 |
| - private let wrapped: Wrapped |
| 71 | + /// The interceptor specified for this operation. |
| 72 | + public let interceptor: any ServerInterceptor |
77 | 73 |
|
78 |
| - private init(wrapped: Wrapped) { |
79 |
| - self.wrapped = wrapped |
| 74 | + private let subject: Subject |
| 75 | + |
| 76 | + private init(interceptor: any ServerInterceptor, appliesTo: Subject) { |
| 77 | + self.interceptor = interceptor |
| 78 | + self.subject = appliesTo |
80 | 79 | }
|
81 | 80 |
|
82 |
| - /// Get the ``ServerInterceptor`` associated with this ``ServerInterceptorOperation``. |
83 |
| - public var interceptor: any ServerInterceptor { |
84 |
| - switch self.wrapped { |
85 |
| - case .allServices(let interceptor): |
86 |
| - return interceptor |
87 |
| - case .serviceSpecific(let interceptor, _): |
88 |
| - return interceptor |
89 |
| - case .methodSpecific(let interceptor, _): |
90 |
| - return interceptor |
91 |
| - } |
| 81 | + /// Create an operation, specifying which ``ServerInterceptor`` to apply and to which ``Subject``. |
| 82 | + /// - Parameters: |
| 83 | + /// - interceptor: The ``ServerInterceptor`` to register with the server. |
| 84 | + /// - subject: The ``Subject`` to which the `interceptor` applies. |
| 85 | + /// - Returns: A ``ServerInterceptorOperation``. |
| 86 | + public static func apply(_ interceptor: any ServerInterceptor, to subject: Subject) -> Self { |
| 87 | + Self(interceptor: interceptor, appliesTo: subject) |
92 | 88 | }
|
93 | 89 |
|
94 | 90 | /// Returns whether this ``ServerInterceptorOperation`` applies to the given `descriptor`.
|
95 | 91 | /// - Parameter descriptor: A ``MethodDescriptor`` for which to test whether this interceptor applies.
|
96 | 92 | /// - Returns: `true` if this interceptor applies to the given `descriptor`, or `false` otherwise.
|
97 |
| - public func applies(to descriptor: MethodDescriptor) -> Bool { |
98 |
| - switch self.wrapped { |
99 |
| - case .allServices: |
100 |
| - return true |
101 |
| - case .serviceSpecific(_, let services): |
102 |
| - return services.contains(descriptor.service) |
103 |
| - case .methodSpecific(_, let methods): |
104 |
| - return methods.contains(descriptor) |
105 |
| - } |
| 93 | + public func _applies(to descriptor: MethodDescriptor) -> Bool { |
| 94 | + self.subject.applies(to: descriptor) |
106 | 95 | }
|
107 | 96 | }
|
0 commit comments