Files

121 lines
3.0 KiB
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 Name {
/// A name (usually multi-character) prefixed with `--` (2 dashes) or
/// equivalent.
case long(String)
/// A single character name prefixed with `-` (1 dash) or equivalent.
///
/// Usually supports mixing multiple short names with a single dash, i.e.
/// `-ab` is equivalent to `-a -b`.
case short(Character, allowingJoined: Bool = false)
/// A name (usually multi-character) prefixed with `-` (1 dash).
case longWithSingleDash(String)
}
extension Name {
init(_ baseName: Substring) {
assert(
baseName.first == "-", "Attempted to create name for unprefixed argument")
if baseName.hasPrefix("--") {
self = .long(String(baseName.dropFirst(2)))
} else if baseName.count == 2, let name = baseName.last {
// single character "-x" style
self = .short(name)
} else {
// long name with single dash
self = .longWithSingleDash(String(baseName.dropFirst()))
}
}
}
// short argument names based on the synopsisString
// this will put the single - options before the -- options
extension Name: Comparable {
static func < (lhs: Name, rhs: Name) -> Bool {
lhs.synopsisString < rhs.synopsisString
}
}
extension Name: Hashable {}
extension Name {
enum Case: Equatable {
case long
case short
case longWithSingleDash
}
var `case`: Case {
switch self {
case .short:
return .short
case .longWithSingleDash:
return .longWithSingleDash
case .long:
return .long
}
}
}
extension Name {
var synopsisString: String {
switch self {
case .long(let n):
return "--\(n)"
case .short(let n, _):
return "-\(n)"
case .longWithSingleDash(let n):
return "-\(n)"
}
}
var valueString: String {
switch self {
case .long(let n):
return n
case .short(let n, _):
return String(n)
case .longWithSingleDash(let n):
return n
}
}
var allowsJoined: Bool {
switch self {
case .short(_, let allowingJoined):
return allowingJoined
default:
return false
}
}
/// The instance to match against user input -- this always has
/// `allowingJoined` as `false`, since that's the way input is parsed.
var nameToMatch: Name {
switch self {
case .long, .longWithSingleDash: return self
case .short(let c, _): return .short(c)
}
}
}
extension BidirectionalCollection where Element == Name {
var preferredName: Name? {
first { $0.case != .short } ?? first
}
var partitioned: [Name] {
filter { $0.case == .short } + filter { $0.case != .short }
}
}