Skip to content

Instantly share code, notes, and snippets.

@zastrozzi
Last active July 3, 2023 22:48
Show Gist options
  • Select an option

  • Save zastrozzi/f36d199613a8bcd24c7e50173ba2011a to your computer and use it in GitHub Desktop.

Select an option

Save zastrozzi/f36d199613a8bcd24c7e50173ba2011a to your computer and use it in GitHub Desktop.
Async Convertible Command extension
import Vapor
// Standard async configure function
public func configure(_ app: Application) async throws {
app.commands.use(Cowsay(), as: "cowsay")
}
public protocol AsyncConvertibleCommand: Command, AsyncCommand, AnyAsyncCommand {
}
extension AsyncConvertibleCommand {
public func run(using context: CommandContext, signature: Signature) throws {
let promise = context.application.eventLoopGroup.any().makePromise(of: Void.self)
promise.completeWithTask {
try await self.run(using: context, signature: signature)
}
}
public func run(using context: inout CommandContext) throws {
var context = context
let signature = try Signature(from: &context.input)
guard context.input.arguments.isEmpty else {
let input = context.input.arguments.joined(separator: " ")
throw Abort(.unprocessableEntity, reason: "Unknown input \(input)")
}
let promise = context.application.eventLoopGroup.any().makePromise(of: Void.self)
context.application.running = .start(using: promise)
promise.futureResult.whenComplete { [context] res in
context.application.running?.stop()
}
promise.completeWithTask { [context] in
try await self.run(using: context, signature: signature)
}
}
public func run(using context: inout CommandContext) async throws {
var context = context
let signature = try Signature(from: &context.input)
guard context.input.arguments.isEmpty else {
let input = context.input.arguments.joined(separator: " ")
throw Abort(.unprocessableEntity, reason: "Unknown input \(input)")
}
let promise = context.application.eventLoopGroup.any().makePromise(of: Void.self)
promise.completeWithTask { [context] in
try await self.run(using: context, signature: signature)
}
}
public func outputAutoComplete(using context: inout CommandContext) {
// do nothing
}
public func outputHelp(using context: inout CommandContext) {
// do nothing
}
public func renderCompletionFunctions(using context: CommandContext, shell: Shell) -> String {
return ""
}
}
struct Cowsay: AsyncConvertibleCommand {
struct Signature: CommandSignature {
@Argument(name: "message")
var message: String
@Option(name: "eyes", short: "e")
var eyes: String?
@Option(name: "tongue", short: "t")
var tongue: String?
}
var help: String {
"Generates ASCII picture of a cow with a message."
}
func run(using context: CommandContext, signature: Signature) async throws {
context.console.print("start waiting")
try await Task.sleep(nanoseconds: 10_000_000_000)
let eyes = signature.eyes ?? "oo"
let tongue = signature.tongue ?? " "
let cow = #"""
< $M >
\ ^__^
\ ($E)\_______
(__)\ )\/\
$T ||----w |
|| ||
"""#.replacingOccurrences(of: "$M", with: signature.message)
.replacingOccurrences(of: "$E", with: eyes)
.replacingOccurrences(of: "$T", with: tongue)
context.console.print(cow)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment