diff --git a/Sources/Hummingbird/Application.swift b/Sources/Hummingbird/Application.swift index 7d2640c44..76d705393 100644 --- a/Sources/Hummingbird/Application.swift +++ b/Sources/Hummingbird/Application.swift @@ -42,7 +42,7 @@ public enum EventLoopGroupProvider { } /// Protocol for an Application. Brings together all the components of Hummingbird together -public protocol ApplicationProtocol: Service where Context: InstantiableRequestContext, Context.Source == ServerRequestContextSource { +public protocol ApplicationProtocol: Service where Context: InitializableFromSource { /// Responder that generates a response from a requests and context associatedtype Responder: HTTPResponder /// Context passed with Request to responder @@ -173,7 +173,7 @@ extension ApplicationProtocol { /// try await app.runService() /// ``` /// Editing the application setup after calling `runService` will produce undefined behaviour. -public struct Application: ApplicationProtocol where Responder.Context: InstantiableRequestContext, Responder.Context.Source == ServerRequestContextSource { +public struct Application: ApplicationProtocol where Responder.Context: InitializableFromSource { // MARK: Member variables /// event loop group used by application diff --git a/Sources/Hummingbird/Server/RequestContext.swift b/Sources/Hummingbird/Server/RequestContext.swift index d680ea064..dd608272a 100644 --- a/Sources/Hummingbird/Server/RequestContext.swift +++ b/Sources/Hummingbird/Server/RequestContext.swift @@ -2,7 +2,7 @@ // // This source file is part of the Hummingbird server framework project // -// Copyright (c) 2021-2023 the Hummingbird authors +// Copyright (c) 2021-2024 the Hummingbird authors // Licensed under Apache License v2.0 // // See LICENSE.txt for license information @@ -34,26 +34,6 @@ public struct EndpointPath: Sendable { private let _value: NIOLockedValueBox } -/// Protocol for request context source -public protocol RequestContextSource { - /// ByteBuffer allocator - var allocator: ByteBufferAllocator { get } - /// Request Logger - var logger: Logger { get } -} - -/// RequestContext source for server applications -public struct ServerRequestContextSource: RequestContextSource { - public init(channel: any Channel, logger: Logger) { - self.channel = channel - self.logger = logger - } - - public let channel: Channel - public let logger: Logger - public var allocator: ByteBufferAllocator { self.channel.allocator } -} - /// Request context values required by Hummingbird itself. public struct CoreRequestContextStorage: Sendable { /// ByteBuffer allocator used by request @@ -78,17 +58,10 @@ public struct CoreRequestContextStorage: Sendable { } } -/// A RequestContext that can be built from some source -public protocol InstantiableRequestContext: Sendable { - associatedtype Source - /// Initialise RequestContext from source - init(source: Source) -} - /// Protocol that all request contexts should conform to. Holds data associated with /// a request. Provides context for request processing -public protocol RequestContext: InstantiableRequestContext { - associatedtype Source: RequestContextSource = ServerRequestContextSource +public protocol RequestContext: InitializableFromSource { + associatedtype Source: RequestContextSource = ApplicationRequestContextSource associatedtype Decoder: RequestDecoder = JSONDecoder associatedtype Encoder: ResponseEncoder = JSONEncoder diff --git a/Sources/Hummingbird/Server/RequestContextSource.swift b/Sources/Hummingbird/Server/RequestContextSource.swift new file mode 100644 index 000000000..6a6c0de90 --- /dev/null +++ b/Sources/Hummingbird/Server/RequestContextSource.swift @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Hummingbird server framework project +// +// Copyright (c) 2021-2024 the Hummingbird authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See hummingbird/CONTRIBUTORS.txt for the list of Hummingbird authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import Logging +import NIOCore + +/// Protocol for source of request contexts +public protocol RequestContextSource { + /// ByteBuffer allocator + var allocator: ByteBufferAllocator { get } + /// Request Logger + var logger: Logger { get } +} + +/// RequestContext source for contexts created by ``Application``. +public struct ApplicationRequestContextSource: RequestContextSource { + public init(channel: any Channel, logger: Logger) { + self.channel = channel + self.logger = logger + } + + public let channel: Channel + public let logger: Logger + public var allocator: ByteBufferAllocator { self.channel.allocator } +} diff --git a/Sources/Hummingbird/Utils/InitializableFromSource.swift b/Sources/Hummingbird/Utils/InitializableFromSource.swift new file mode 100644 index 000000000..1c4bde9e3 --- /dev/null +++ b/Sources/Hummingbird/Utils/InitializableFromSource.swift @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Hummingbird server framework project +// +// Copyright (c) 2021-2024 the Hummingbird authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See hummingbird/CONTRIBUTORS.txt for the list of Hummingbird authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A type that can be initialized from another type +public protocol InitializableFromSource: Sendable { + associatedtype Source + /// Initialise RequestContext from source + init(source: Source) +} diff --git a/Sources/HummingbirdTesting/RouterTestFramework.swift b/Sources/HummingbirdTesting/RouterTestFramework.swift index 52927df61..8c9bff956 100644 --- a/Sources/HummingbirdTesting/RouterTestFramework.swift +++ b/Sources/HummingbirdTesting/RouterTestFramework.swift @@ -25,14 +25,14 @@ import NIOPosix import ServiceLifecycle /// Test sending requests directly to router. This does not setup a live server -struct RouterTestFramework: ApplicationTestFramework where Responder.Context: InstantiableRequestContext { +struct RouterTestFramework: ApplicationTestFramework where Responder.Context: InitializableFromSource { let responder: Responder let makeContext: @Sendable (Logger) -> Responder.Context let services: [any Service] let logger: Logger let processesRunBeforeServerStart: [@Sendable () async throws -> Void] - init(app: App) async throws where App.Responder == Responder, Responder.Context: InstantiableRequestContext { + init(app: App) async throws where App.Responder == Responder, Responder.Context: InitializableFromSource { self.responder = try await app.responder self.processesRunBeforeServerStart = app.processesRunBeforeServerStart self.services = app.services diff --git a/Tests/HummingbirdTests/ApplicationTests.swift b/Tests/HummingbirdTests/ApplicationTests.swift index 5aea8f628..1cb4c085d 100644 --- a/Tests/HummingbirdTests/ApplicationTests.swift +++ b/Tests/HummingbirdTests/ApplicationTests.swift @@ -556,9 +556,8 @@ final class ApplicationTests: XCTestCase { /// test we can create an application that accepts a responder with an empty context func testEmptyRequestContext() async throws { - struct EmptyRequestContext: InstantiableRequestContext { - typealias Source = ServerRequestContextSource - + struct EmptyRequestContext: InitializableFromSource { + typealias Source = ApplicationRequestContextSource init(source: Source) {} } let app = Application(