1
0

InputKey.swift 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. //===----------------------------------------------------------------------===//
  2. //
  3. // This source file is part of the Swift Argument Parser open source project
  4. //
  5. // Copyright (c) 2022 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. /// Represents the path to a parsed field, annotated with ``Flag``, ``Option``
  12. /// or ``Argument``.
  13. ///
  14. /// Fields that are directly declared on a ``ParsableCommand`` have a path of
  15. /// length 1, while fields that are declared indirectly (and included via an
  16. /// option group) have longer paths.
  17. struct InputKey: Hashable {
  18. /// The name of the input key.
  19. var name: String
  20. /// The path through the field's parents, if any.
  21. var path: [String]
  22. /// The full path of the field.
  23. var fullPath: [String] { path + [name] }
  24. /// Constructs a new input key, cleaning the name, with the specified parent.
  25. ///
  26. /// - Parameters:
  27. /// - name: The name of the key.
  28. /// - parent: The input key of the parent.
  29. init(name: String, parent: InputKey?) {
  30. // Property wrappers have underscore-prefixed names, so we remove the
  31. // leading `_`, if present.
  32. self.name =
  33. name.first == "_"
  34. ? String(name.dropFirst(1))
  35. : name
  36. self.path = parent?.fullPath ?? []
  37. }
  38. /// Constructs a new input key from the given coding key and parent path.
  39. ///
  40. /// - Parameters:
  41. /// - codingKey: The base ``CodingKey``. Leading underscores in `codingKey`
  42. /// is preserved.
  43. /// - path: The list of ``CodingKey`` values that lead to this one. `path`
  44. /// may be empty.
  45. init(codingKey: CodingKey, path: [CodingKey]) {
  46. self.name = codingKey.stringValue
  47. self.path = path.map { $0.stringValue }
  48. }
  49. }
  50. extension InputKey: CustomStringConvertible {
  51. var description: String {
  52. fullPathString
  53. }
  54. }
  55. extension InputKey {
  56. private static var separator: Character { "." }
  57. var fullPathString: String {
  58. fullPath.joined(separator: .init(Self.separator))
  59. }
  60. init?(fullPathString: String) {
  61. let fullPath = fullPathString.split(separator: Self.separator).map(
  62. String.init)
  63. guard let name = fullPath.last else { return nil }
  64. self.name = name
  65. self.path = fullPath.dropLast()
  66. }
  67. }