Skip to content

Commit aab00ca

Browse files
committed
nonisolated pattern matching
1 parent f6b72be commit aab00ca

File tree

2 files changed

+67
-7
lines changed

2 files changed

+67
-7
lines changed

FlyingFox/Sources/HTTPRoute.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,15 @@ public extension HTTPRoute {
194194
fatalError()
195195
}
196196

197+
#if compiler(>=6.2)
198+
nonisolated(nonsending) static func ~= (route: HTTPRoute, request: HTTPRequest) async -> Bool {
199+
await route.patternMatch(request: request)
200+
}
201+
#else
197202
static func ~= (route: HTTPRoute, request: HTTPRequest) async -> Bool {
198203
await route.patternMatch(request: request)
199204
}
205+
#endif
200206
}
201207

202208
private extension HTTPRoute {
@@ -224,13 +230,23 @@ private extension HTTPRoute {
224230
return nil
225231
}
226232

233+
#if compiler(>=6.2)
234+
nonisolated(nonsending) func patternMatch(request: HTTPRequest) async -> Bool {
235+
guard patternMatch(query: request.query),
236+
patternMatch(headers: request.headers),
237+
await patternMatch(body: request.bodySequence) else { return false }
238+
239+
return patternMatch(method: request.method, path: request.path)
240+
}
241+
#else
227242
func patternMatch(request: HTTPRequest) async -> Bool {
228243
guard patternMatch(query: request.query),
229244
patternMatch(headers: request.headers),
230245
await patternMatch(body: request.bodySequence) else { return false }
231246

232247
return patternMatch(method: request.method, path: request.path)
233248
}
249+
#endif
234250

235251
func patternMatch(method: HTTPMethod, path: String) -> Bool {
236252
guard self.methods.contains(method) else {
@@ -265,6 +281,22 @@ private extension HTTPRoute {
265281
}
266282
}
267283

284+
#if compiler(>=6.2)
285+
nonisolated(nonsending) func patternMatch(body request: HTTPBodySequence) async -> Bool {
286+
guard let body = body else { return true }
287+
288+
guard request.canReplay else {
289+
// body is large and can only be iterated one-time only so should not match it
290+
return false
291+
}
292+
293+
do {
294+
return try await body.evaluate(request.get())
295+
} catch {
296+
return false
297+
}
298+
}
299+
#else
268300
func patternMatch(body request: HTTPBodySequence) async -> Bool {
269301
guard let body = body else { return true }
270302

@@ -279,6 +311,7 @@ private extension HTTPRoute {
279311
return false
280312
}
281313
}
314+
#endif
282315

283316
static func components(for target: String) -> (
284317
methods: Set<HTTPMethod>,

FlyingFox/Sources/Handlers/RoutedHTTPHandler.swift

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,12 @@ public struct RoutedHTTPHandler: HTTPHandler, Sendable {
8181
public func handleRequest(_ request: HTTPRequest) async throws -> HTTPResponse {
8282
for entry in handlers {
8383
do {
84-
if await entry.route ~= request {
85-
return try await HTTPRequest.$matchedRoute.withValue(entry.route) {
86-
return try await entry.handler.handleRequest(request)
87-
}
84+
if let response = try await Self.handleMatchedRequest(
85+
request,
86+
to: entry.route,
87+
handler: entry.handler.handleRequest
88+
) {
89+
return response
8890
}
8991
} catch is HTTPUnhandledError {
9092
continue
@@ -136,9 +138,21 @@ public extension RoutedHTTPHandler {
136138
}
137139
}
138140

139-
#if compiler(>=6.0)
140141
public extension RoutedHTTPHandler {
141-
142+
#if compiler(>=6.2)
143+
nonisolated(nonsending) static func handleMatchedRequest(
144+
_ request: HTTPRequest,
145+
to route: HTTPRoute,
146+
handler: (HTTPRequest) async throws -> HTTPResponse
147+
) async throws -> HTTPResponse? {
148+
if await route ~= request {
149+
return try await HTTPRequest.$matchedRoute.withValue(route) {
150+
return try await handler(request)
151+
}
152+
}
153+
return nil
154+
}
155+
#elseif compiler(>=6.0)
142156
static func handleMatchedRequest(
143157
isolation: isolated (any Actor)? = #isolation,
144158
_ request: HTTPRequest,
@@ -153,8 +167,21 @@ public extension RoutedHTTPHandler {
153167
}
154168
return nil
155169
}
156-
}
170+
#else
171+
static func handleMatchedRequest(
172+
_ request: HTTPRequest,
173+
to route: HTTPRoute,
174+
handler: (HTTPRequest) async throws -> HTTPResponse
175+
) async throws -> HTTPResponse? {
176+
if await route ~= request {
177+
return try await HTTPRequest.$matchedRoute.withValue(route) {
178+
return try await handler(request)
179+
}
180+
}
181+
return nil
182+
}
157183
#endif
184+
}
158185

159186
extension RoutedHTTPHandler: RangeReplaceableCollection {
160187
public typealias Index = Array<Element>.Index

0 commit comments

Comments
 (0)