InputOrigin.swift 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. //===----------------------------------------------------------------------===//
  2. //
  3. // This source file is part of the Swift Argument Parser open source project
  4. //
  5. // Copyright (c) 2020 Apple Inc. and the Swift project authors
  6. // Licensed under Apache License v2.0 with Runtime Library Exception
  7. //
  8. // See https://swift.org/LICENSE.txt for license information
  9. //
  10. //===----------------------------------------------------------------------===//
  11. /// Specifies where a given input came from.
  12. ///
  13. /// When reading from the command line, a value might originate from a single
  14. /// index, multiple indices, or from part of an index. For this command:
  15. ///
  16. /// struct Example: ParsableCommand {
  17. /// @Flag(name: .short) var verbose = false
  18. /// @Flag(name: .short) var expert = false
  19. ///
  20. /// @Option var count: Int
  21. /// }
  22. ///
  23. /// ...with this usage:
  24. ///
  25. /// $ example -ve --count 5
  26. ///
  27. /// The parsed value for the `count` property will come from indices `1` and
  28. /// `2`, while the value for `verbose` will come from index `1`, sub-index `0`.
  29. struct InputOrigin: Equatable, ExpressibleByArrayLiteral {
  30. enum Element: Comparable, Hashable {
  31. /// The input value came from a property's default value, not from a
  32. /// command line argument.
  33. case defaultValue
  34. /// The input value came from the specified index in the argument string.
  35. case argumentIndex(SplitArguments.Index)
  36. var baseIndex: Int? {
  37. switch self {
  38. case .defaultValue:
  39. return nil
  40. case .argumentIndex(let i):
  41. return i.inputIndex.rawValue
  42. }
  43. }
  44. var subIndex: Int? {
  45. switch self {
  46. case .defaultValue:
  47. return nil
  48. case .argumentIndex(let i):
  49. switch i.subIndex {
  50. case .complete: return nil
  51. case .sub(let n): return n
  52. }
  53. }
  54. }
  55. }
  56. private var _elements: Set<Element> = []
  57. var elements: [Element] {
  58. Array(_elements).sorted()
  59. }
  60. var firstElement: Element {
  61. guard !elements.isEmpty else {
  62. fatalError("Invalid 'InputOrigin' with no positions")
  63. }
  64. return elements[0]
  65. }
  66. init(elements: [Element]) {
  67. _elements = Set(elements)
  68. }
  69. init(element: Element) {
  70. _elements = Set([element])
  71. }
  72. init(arrayLiteral elements: Element...) {
  73. self.init(elements: elements)
  74. }
  75. init(argumentIndex: SplitArguments.Index) {
  76. self.init(element: .argumentIndex(argumentIndex))
  77. }
  78. mutating func insert(_ other: Element) {
  79. guard !_elements.contains(other) else { return }
  80. _elements.insert(other)
  81. }
  82. func inserting(_ other: Element) -> Self {
  83. guard !_elements.contains(other) else { return self }
  84. var result = self
  85. result.insert(other)
  86. return result
  87. }
  88. mutating func formUnion(_ other: InputOrigin) {
  89. _elements.formUnion(other._elements)
  90. }
  91. func forEach(_ closure: (Element) -> Void) {
  92. _elements.forEach(closure)
  93. }
  94. }
  95. extension InputOrigin {
  96. var isDefaultValue: Bool {
  97. _elements.count == 1 && _elements.first == .defaultValue
  98. }
  99. }
  100. extension InputOrigin.Element {
  101. static func < (lhs: Self, rhs: Self) -> Bool {
  102. switch (lhs, rhs) {
  103. case (.argumentIndex(let l), .argumentIndex(let r)):
  104. return l < r
  105. case (.argumentIndex, .defaultValue):
  106. return true
  107. case (.defaultValue, _):
  108. return false
  109. }
  110. }
  111. }