import Foundation import HTTPTypes import Hummingbird import Localization public extension Negotiate { // MARK: Methods /// The language to serve a request in. /// /// The `lang` query parameter wins as a deliberate override; failing that, a leading path segment naming a supported language pins it, so an /// unrouted path under a language's prefix answers in that language. Anything naming no supported language is ignored, leaving the /// `Accept-Language` header and its fallback to the default. /// /// Called where the answer is used rather than stamped onto every request on the way past: page routes that pin their language by URL never ask. /// - Parameter request: the request to negotiate for. /// - Returns: the identifier of the supported language to serve. func callAsFunction( for request: Request ) -> String { let requested = request.uri.queryParameters[.Parameter.language].map(String.init) ?? request.uri.path.split(separator: "/").first.map(String.init) return callAsFunction( requested: requested, acceptLanguage: request.headers[.acceptLanguage] ) } } // MARK: - Constants private extension Substring { /// A namespace for the query parameters the negotiation reads. enum Parameter { /// The query parameter carrying an explicit language choice; the site's language switcher appends it to the current path. static let language: Substring = "lang" } }