doxy/Library/Sources/Public/Builders/AppBuilder.swift

95 lines
2.6 KiB
Swift

import Hummingbird
import Logging
/// A type that sets and builds an application that would be ready to run in the executable target.
public struct AppBuilder {
// MARK: Properties
private let name: String
private let archivesPath: String
private let environment: Environment
// MARK: Initialisers
/// Initialises this type.
/// - Parameters:
/// - name: A name for the app to build.
/// - archivesPath: A relative path to the location of the *DocC* archive containers.
public init(
name: String,
archivesPath: String
) {
self.name = name
self.archivesPath = archivesPath
self.environment = Environment()
}
// MARK: Functions
/// Sets and builds a ready-to-use application.
///
/// The application this function builds have the following features:
/// * proxy requests to any available *DocC* archive container in the ``AppArguments/archivesPath`` location;
/// * log any request to any available *DocC* archive container in the application console.
///
/// - Parameter arguments: A set in input parameters used while building the application.
/// - Returns: A configured, functional application that is ready to use.
public func callAsFunction(_ arguments: some AppArguments) async throws -> some ApplicationProtocol {
let logger = logger(level: arguments.logLevel)
let router = router(logger: logger)
return Application(
router: router,
configuration: .init(
address: .hostname(
arguments.hostname,
port: arguments.port
),
serverName: name
),
logger: logger
)
}
}
// MARK: - Helpers
private extension AppBuilder {
// MARK: Type aliases
typealias AppRequestContext = BasicRequestContext
// MARK: Functions
func logger(level: Logger.Level?) -> Logger {
var logger = Logger(label: name)
logger.logLevel = level
?? environment.logLevel.flatMap { Logger.Level(rawValue: $0) ?? .info }
?? .info
return logger
}
func router(logger: Logger) -> Router<AppRequestContext> {
let router = Router()
router.addMiddleware {
LogRequestsMiddleware(logger.logLevel)
DocCMiddleware(archivesPath, logger: logger)
}
ArchiveController(
archivesPath,
logger: logger
)
.register(to: router)
return router
}
}