Files
phbar/Sources/phbar/cli.swift
T

63 lines
2.0 KiB
Swift

// The Swift Programming Language
// https://docs.swift.org/swift-book
//
// Swift Argument Parser
// https://swiftpackageindex.com/apple/swift-argument-parser/documentation
import ArgumentParser
import Foundation
@main
struct phbar: ParsableCommand {
static let configuration = CommandConfiguration(
commandName: "phbar",
abstract: "Modular status bar for macOS.",
discussion: """
pmenu reads a list of newline-separated items from stdin and presents them to the user.
When the user selects an item and presses Return, their choice is printed to stdout and pmenu terminates.
Entering text will narrow the items to those matching the tokens in the input.
""",
version: "1.0.0",
subcommands: [start.self]
)
}
extension phbar {
struct Error: LocalizedError {
let message: String
let underlyingError: Swift.Error?
init(_ message: String, underlyingError: Swift.Error? = nil) {
self.message = message
self.underlyingError = underlyingError
}
var errorDescription: String? {
guard let underlyingError else { return message }
if let decodingError = underlyingError as? DecodingError {
return "\(message): \(Self.describe(decodingError))"
}
return "\(message): \(underlyingError.localizedDescription)"
}
private static func describe(_ error: DecodingError) -> String {
switch error {
case .keyNotFound(let key, let context):
let path = context.codingPath.map(\.stringValue).joined(separator: ".")
return "missing key '\(key.stringValue)' at \(path.isEmpty ? "root" : path)"
case .typeMismatch(let type, let context):
let path = context.codingPath.map(\.stringValue).joined(separator: ".")
return "type mismatch for \(type) at \(path)"
case .valueNotFound(let type, let context):
let path = context.codingPath.map(\.stringValue).joined(separator: ".")
return "missing value of type \(type) at \(path)"
case .dataCorrupted(let context):
return "corrupted data → \(context.debugDescription)"
@unknown default:
return error.localizedDescription
}
}
}
}