Skip to content

Commit

Permalink
Replace RequestContext initialization parameters with associatedtype
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-fowler committed Jun 10, 2024
1 parent ea60c9b commit 2a76b9f
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 39 deletions.
6 changes: 4 additions & 2 deletions Sources/Hummingbird/Application.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,10 @@ extension ApplicationProtocol {
logger: self.logger
) { request, channel in
let context = Self.Responder.Context(
channel: channel,
logger: self.logger.with(metadataKey: "hb_id", value: .stringConvertible(RequestID()))
source: .init(
channel: channel,
logger: self.logger.with(metadataKey: "hb_id", value: .stringConvertible(RequestID()))
)
)
// respond to request
var response: Response
Expand Down
43 changes: 28 additions & 15 deletions Sources/Hummingbird/Server/RequestContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ public struct EndpointPath: Sendable {
private let _value: NIOLockedValueBox<String?>
}

/// Protocol for request context source
public protocol RequestContextSource {
/// ByteBuffer allocator
var allocator: ByteBufferAllocator { get }
/// Request Logger
var logger: Logger { get }
}

/// Request context values required by Hummingbird itself.
public struct CoreRequestContext: Sendable {
/// ByteBuffer allocator used by request
Expand All @@ -49,11 +57,10 @@ public struct CoreRequestContext: Sendable {

@inlinable
public init(
allocator: ByteBufferAllocator,
logger: Logger
source: some RequestContextSource
) {
self.allocator = allocator
self.logger = logger
self.allocator = source.allocator
self.logger = source.logger
self.endpointPath = .init()
self.parameters = .init()
}
Expand All @@ -62,9 +69,12 @@ public struct CoreRequestContext: Sendable {
/// Protocol that all request contexts should conform to. Holds data associated with
/// a request. Provides context for request processing
public protocol BaseRequestContext: Sendable {
associatedtype Source: RequestContextSource
associatedtype Decoder: RequestDecoder = JSONDecoder
associatedtype Encoder: ResponseEncoder = JSONEncoder

/// Initialise RequestContext from source
init(source: Source)
/// Core context
var coreContext: CoreRequestContext { get set }
/// Maximum upload size allowed for routes that don't stream the request payload. This
Expand Down Expand Up @@ -116,13 +126,19 @@ extension BaseRequestContext where Encoder == JSONEncoder {
}
}

/// 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 { channel.allocator }
}
/// Protocol for a request context that can be created from a NIO Channel
public protocol RequestContext: BaseRequestContext {
/// initialize an `RequestContext`
/// - Parameters:
/// - channel: Channel that initiated this request
/// - logger: Logger used for this request
init(channel: Channel, logger: Logger)
public protocol RequestContext: BaseRequestContext where Source == ServerRequestContextSource {
}

/// Implementation of a basic request context that supports everything the Hummingbird library needs
Expand All @@ -134,10 +150,7 @@ public struct BasicRequestContext: RequestContext {
/// - Parameters:
/// - allocator: Allocator
/// - logger: Logger
public init(channel: Channel, logger: Logger) {
self.coreContext = .init(
allocator: channel.allocator,
logger: logger
)
public init(source: Source) {
self.coreContext = .init(source: source)
}
}
4 changes: 2 additions & 2 deletions Sources/HummingbirdRouter/RouterBuilderContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ public struct BasicRouterRequestContext: RequestContext, RouterRequestContext {
public var routerContext: RouterBuilderContext
public var coreContext: CoreRequestContext

public init(channel: Channel, logger: Logger) {
self.coreContext = .init(allocator: channel.allocator, logger: logger)
public init(source: Source) {
self.coreContext = .init(source: source)
self.routerContext = .init()
}
}
6 changes: 4 additions & 2 deletions Sources/HummingbirdTesting/RouterTestFramework.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ struct RouterTestFramework<Responder: HTTPResponder>: ApplicationTestFramework w
self.logger = app.logger
self.makeContext = { logger in
Responder.Context(
channel: NIOAsyncTestingChannel(),
logger: logger
source: .init(
channel: NIOAsyncTestingChannel(),
logger: logger
)
)
}
}
Expand Down
6 changes: 2 additions & 4 deletions Tests/HummingbirdRouterTests/RouterTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -450,15 +450,13 @@ public struct TestRouterContext2: RouterRequestContext, RequestContext {
public var routerContext: RouterBuilderContext
/// core context
public var coreContext: CoreRequestContext
/// Connected remote host
public var remoteAddress: SocketAddress? { nil }

/// additional data
public var string: String

public init(channel: Channel, logger: Logger) {
public init(source: Source) {
self.routerContext = .init()
self.coreContext = .init(allocator: channel.allocator, logger: logger)
self.coreContext = .init(source: source)
self.string = ""
}
}
17 changes: 7 additions & 10 deletions Tests/HummingbirdTests/ApplicationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -379,8 +379,8 @@ final class ApplicationTests: XCTestCase {
return encoder
}

init(channel: Channel, logger: Logger) {
self.coreContext = .init(allocator: channel.allocator, logger: logger)
init(source: Source) {
self.coreContext = .init(source: source)
}
}
struct Name: ResponseCodable {
Expand Down Expand Up @@ -449,8 +449,8 @@ final class ApplicationTests: XCTestCase {

func testMaxUploadSize() async throws {
struct MaxUploadRequestContext: RequestContext {
init(channel: Channel, logger: Logger) {
self.coreContext = .init(allocator: channel.allocator, logger: logger)
init(source: Source) {
self.coreContext = .init(source: source)
}

var coreContext: CoreRequestContext
Expand Down Expand Up @@ -486,12 +486,9 @@ final class ApplicationTests: XCTestCase {
// socket address
let remoteAddress: SocketAddress?

init(
channel: Channel,
logger: Logger
) {
self.coreContext = .init(allocator: channel.allocator, logger: logger)
self.remoteAddress = channel.remoteAddress
init(source: Source) {
self.coreContext = .init(source: source)
self.remoteAddress = source.channel.remoteAddress
}
}
let router = Router(context: SocketAddressRequestContext.self)
Expand Down
4 changes: 2 additions & 2 deletions Tests/HummingbirdTests/RouterTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -603,8 +603,8 @@ final class RouterTests: XCTestCase {
}

struct TestRouterContext2: RequestContext {
init(channel: Channel, logger: Logger) {
self.coreContext = .init(allocator: channel.allocator, logger: logger)
init(source: Source) {
self.coreContext = .init(source: source)
self.string = ""
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ class HummingBirdURLEncodedTests: XCTestCase {
struct URLEncodedCodingRequestContext: RequestContext {
var coreContext: CoreRequestContext

init(channel: Channel, logger: Logger) {
self.coreContext = .init(allocator: channel.allocator, logger: logger)
init(source: Source) {
self.coreContext = .init(source: source)
}

var requestDecoder: URLEncodedFormDecoder { .init() }
Expand Down

0 comments on commit 2a76b9f

Please sign in to comment.