mirror of
https://github.com/apple/swift-argument-parser.git
synced 2026-06-06 20:18:23 +00:00
Support for generating shell completion scripts for `ParsableCommand` types, with customization points for `ExpressibleByArgument` types and individual arguments and options. Zsh and Bash are supported in this initial release.
84 lines
2.4 KiB
Swift
84 lines
2.4 KiB
Swift
//===----------------------------------------------------------*- swift -*-===//
|
||
//
|
||
// This source file is part of the Swift Argument Parser open source project
|
||
//
|
||
// Copyright (c) 2020 Apple Inc. and the Swift project authors
|
||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||
//
|
||
// See https://swift.org/LICENSE.txt for license information
|
||
//
|
||
//===----------------------------------------------------------------------===//
|
||
|
||
enum Parsed<Value> {
|
||
/// The definition of how this value is to be parsed from command-line arguments.
|
||
///
|
||
/// Internally, this wraps an `ArgumentSet`, but that’s not `public` since it’s
|
||
/// an implementation detail.
|
||
case value(Value)
|
||
case definition((InputKey) -> ArgumentSet)
|
||
|
||
internal init(_ makeSet: @escaping (InputKey) -> ArgumentSet) {
|
||
self = .definition(makeSet)
|
||
}
|
||
}
|
||
|
||
/// A type that wraps a `Parsed` instance to act as a property wrapper.
|
||
///
|
||
/// This protocol simplifies the implementations of property wrappers that
|
||
/// wrap the `Parsed` type.
|
||
internal protocol ParsedWrapper: Decodable, ArgumentSetProvider {
|
||
associatedtype Value
|
||
var _parsedValue: Parsed<Value> { get }
|
||
init(_parsedValue: Parsed<Value>)
|
||
}
|
||
|
||
/// A `Parsed`-wrapper whose value type knows how to decode itself. Types that
|
||
/// conform to this protocol can initialize their values directly from a
|
||
/// `Decoder`.
|
||
internal protocol DecodableParsedWrapper: ParsedWrapper
|
||
where Value: Decodable
|
||
{
|
||
init(_parsedValue: Parsed<Value>)
|
||
}
|
||
|
||
extension ParsedWrapper {
|
||
init(_decoder: Decoder) throws {
|
||
guard let d = _decoder as? SingleValueDecoder else {
|
||
throw ParserError.invalidState
|
||
}
|
||
guard let value = d.parsedElement?.value as? Value else {
|
||
throw ParserError.noValue(forKey: d.parsedElement?.key ?? d.key)
|
||
}
|
||
|
||
self.init(_parsedValue: .value(value))
|
||
}
|
||
|
||
func argumentSet(for key: InputKey) -> ArgumentSet {
|
||
switch _parsedValue {
|
||
case .value:
|
||
fatalError("Trying to get the argument set from a resolved/parsed property.")
|
||
case .definition(let a):
|
||
return a(key)
|
||
}
|
||
}
|
||
}
|
||
|
||
extension ParsedWrapper where Value: Decodable {
|
||
init(_decoder: Decoder) throws {
|
||
var value: Value
|
||
|
||
do {
|
||
value = try Value.init(from: _decoder)
|
||
} catch {
|
||
if let d = _decoder as? SingleValueDecoder,
|
||
let v = d.parsedElement?.value as? Value {
|
||
value = v
|
||
} else {
|
||
throw error
|
||
}
|
||
}
|
||
|
||
self.init(_parsedValue: .value(value))
|
||
}
|
||
}
|