Skip to content

Add support for async/await where available #326

@sergiocampama

Description

@sergiocampama

async/await is useful for writing clean and concise code for building small CLI tools, especially ones that interact with the network or the file system.

Since @main now supports an async variant, I was able to add such support to a prototype with the following code:

// entry.swift

@available(macOS 12.0, *)
protocol AsyncParsableCommand: ParsableCommand {
    mutating func runAsync() async throws
}

extension ParsableCommand {
    static func main(_ arguments: [String]? = nil) async {
        do {
            var command = try parseAsRoot(arguments)
            if #available(macOS 12.0, *), var asyncCommand = command as? AsyncParsableCommand {
                try await asyncCommand.runAsync()
            } else {
                try command.run()
            }
        } catch {
            exit(withError: error)
        }
    }
}

struct MainCommand: AsyncParsableCommand {
    @Option()
    var name: String = "Anon"

    func runAsync() async throws {
        print("Hello, \(name)")
        // await something...
    }
}

@main
struct MainApp {
    static func main() async {
        await MainCommand.main()
    }
}

Having this be officially supported by swift-argument-parser would be ideal.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions