@@ -2,10 +2,16 @@ import Foundation
2
2
3
3
public protocol HTTPClientMiddleware {
4
4
5
+ //#if swift(>=6.0)
6
+ // typealias Next<T> = @Sendable (HTTPRequestComponents, APIClient.Configs) async throws(HTTPClientMiddlewareError) -> (T, HTTPResponse)
7
+ //#else
8
+ typealias Next < T> = @Sendable ( HTTPRequestComponents, APIClient . Configs) async throws -> ( T , HTTPResponse )
9
+ //#endif
10
+
5
11
func execute< T> (
6
12
request: HTTPRequestComponents ,
7
13
configs: APIClient . Configs ,
8
- next: @escaping @ Sendable ( HTTPRequestComponents , APIClient . Configs ) async throws -> ( T , HTTPResponse )
14
+ next: @escaping Next < T >
9
15
) async throws -> ( T , HTTPResponse )
10
16
}
11
17
@@ -26,6 +32,52 @@ public extension APIClient.Configs {
26
32
}
27
33
}
28
34
35
+ struct HTTPClientMiddlewareError : Error {
36
+
37
+ public let underlying : Error
38
+ private var values : [ PartialKeyPath < Self > : Any ] = [ : ]
39
+
40
+ public init ( _ underlying: Error ) {
41
+ self . underlying = underlying
42
+ }
43
+
44
+ public init ( _ underlying: String ) {
45
+ self . underlying = Errors . custom ( underlying)
46
+ }
47
+
48
+ public subscript< T> ( _ keyPath: WritableKeyPath < Self , T > ) -> T ? {
49
+ get {
50
+ values [ keyPath] as? T
51
+ }
52
+ set {
53
+ values [ keyPath] = newValue
54
+ }
55
+ }
56
+
57
+ public subscript< T> ( _ keyPath: WritableKeyPath < Self , T ? > ) -> T ? {
58
+ get {
59
+ values [ keyPath] as? T
60
+ }
61
+ set {
62
+ values [ keyPath] = newValue
63
+ }
64
+ }
65
+
66
+ public func with< T> ( _ keyPath: WritableKeyPath < Self , T > , _ value: T ) -> HTTPClientMiddlewareError {
67
+ var result = self
68
+ result [ keyPath: keyPath] = value
69
+ return result
70
+ }
71
+ }
72
+
73
+ extension HTTPClientMiddlewareError {
74
+
75
+ var response : HTTPResponse ? {
76
+ get { self [ \. response] }
77
+ set { self [ \. response] = newValue }
78
+ }
79
+ }
80
+
29
81
private extension APIClient . Configs {
30
82
31
83
var httpClientArrayMiddleware : HTTPClientArrayMiddleware {
@@ -36,17 +88,31 @@ private extension APIClient.Configs {
36
88
37
89
private struct HTTPClientArrayMiddleware : HTTPClientMiddleware {
38
90
91
+ typealias AnyNext < T> = @Sendable ( HTTPRequestComponents, APIClient . Configs) async throws -> ( T , HTTPResponse )
92
+
39
93
var middlewares : [ HTTPClientMiddleware ] = [ ]
40
94
41
95
func execute< T> (
42
96
request: HTTPRequestComponents ,
43
97
configs: APIClient . Configs ,
44
- next: @escaping @ Sendable ( HTTPRequestComponents , APIClient . Configs ) async throws -> ( T , HTTPResponse )
98
+ next: @escaping Next < T >
45
99
) async throws -> ( T , HTTPResponse ) {
46
100
var next = next
47
101
for middleware in middlewares {
48
102
next = { [ next] in try await middleware. execute ( request: $0, configs: $1, next: next) }
49
103
}
50
104
return try await next ( request, configs)
51
105
}
106
+
107
+ private func wrapNext< T> ( _ next: @escaping AnyNext < T > ) -> Next < T > {
108
+ { request, configs in
109
+ do {
110
+ return try await next ( request, configs)
111
+ } catch let error as HTTPClientMiddlewareError {
112
+ throw error
113
+ } catch {
114
+ throw HTTPClientMiddlewareError ( error)
115
+ }
116
+ }
117
+ }
52
118
}
0 commit comments