Skip to content

Instantly share code, notes, and snippets.

@MihaelIsaev
Created February 8, 2020 10:27
Show Gist options
  • Save MihaelIsaev/3ed4252db7abb4450e8f369293c9c21b to your computer and use it in GitHub Desktop.
Save MihaelIsaev/3ed4252db7abb4450e8f369293c9c21b to your computer and use it in GitHub Desktop.
import Vapor
public protocol FutureParameter {
associatedtype ResolvedParameter
static var routingSlug: String { get }
static var parameter: PathComponent { get }
static func resolveParameter(_ parameter: String, on app: Application) -> EventLoopFuture<ResolvedParameter>
}
public protocol Parameter {
associatedtype ResolvedParameter
static var routingSlug: String { get }
static var parameter: PathComponent { get }
static func resolveParameter(_ parameter: String) throws -> ResolvedParameter
}
extension FutureParameter {
static var parameter: PathComponent { .parameter(routingSlug.lowercased()) }
}
extension Parameter {
public static var parameter: PathComponent { .parameter(routingSlug.lowercased()) }
}
extension Parameters {
public func grab<T>(_ type: T.Type = T.self, at routingSlug: String = T.routingSlug, on app: Application) -> EventLoopFuture<T.ResolvedParameter> where T: FutureParameter {
app.eventLoopGroup.future().flatMapThrowing {
guard let parameter = self.get(routingSlug.lowercased())
else { throw Abort(.badRequest) }
return parameter
}.flatMap {
T.resolveParameter($0, on: app)
}
}
public func grab<T>(_ type: T.Type = T.self, at routingSlug: String = T.routingSlug, on req: Request) -> EventLoopFuture<T.ResolvedParameter> where T: FutureParameter {
grab(type, at: routingSlug.lowercased(), on: req.application)
}
public func grab<T>(_ type: T.Type = T.self, at routingSlug: String = T.routingSlug) throws -> T.ResolvedParameter where T: Parameter {
guard let parameter = self.get(routingSlug.lowercased())
else { throw Abort(.badRequest, reason: "Unable to find \(routingSlug) in URL params") }
return try T.resolveParameter(parameter)
}
}
extension UUID: Parameter {
public static var routingSlug: String { "id" }
public static func resolveParameter(_ parameter: String) throws -> UUID {
guard let id = UUID(uuidString: parameter) else { throw Abort(.badRequest) }
return id
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment