diff --git a/Sources/ArgumentParser/Documentation.docc/Extensions/Option.md b/Sources/ArgumentParser/Documentation.docc/Extensions/Option.md
index f5a2c9a7..ebb1721d 100644
--- a/Sources/ArgumentParser/Documentation.docc/Extensions/Option.md
+++ b/Sources/ArgumentParser/Documentation.docc/Extensions/Option.md
@@ -2,15 +2,15 @@
## Topics
-### Single Options
+### Single-Value Options
-- ``init(name:parsing:help:completion:)-7slrf``
- ``init(name:parsing:help:completion:)-4yske``
+- ``init(name:parsing:help:completion:)-7slrf``
+- ``init(wrappedValue:name:parsing:help:completion:)-7ilku``
- ``init(name:parsing:help:completion:transform:)-2wf44``
- ``init(name:parsing:help:completion:transform:)-25g7b``
- ``init(wrappedValue:name:parsing:help:completion:transform:)-2llve``
- ``SingleValueParsingStrategy``
-- ``init(wrappedValue:name:parsing:help:completion:)-7ilku``
### Array Options
diff --git a/Sources/ArgumentParser/Parsable Properties/Argument.swift b/Sources/ArgumentParser/Parsable Properties/Argument.swift
index b9ad507d..84a9d0ca 100644
--- a/Sources/ArgumentParser/Parsable Properties/Argument.swift
+++ b/Sources/ArgumentParser/Parsable Properties/Argument.swift
@@ -414,6 +414,7 @@ extension Argument {
/// - transform: A closure that converts a string into this property's
/// element type or throws an error.
@preconcurrency
+ @_disfavoredOverload
public init(
help: ArgumentHelp? = nil,
completion: CompletionKind? = nil,
diff --git a/Sources/ArgumentParser/Parsable Properties/Option.swift b/Sources/ArgumentParser/Parsable Properties/Option.swift
index 27a23f35..9dad1e42 100644
--- a/Sources/ArgumentParser/Parsable Properties/Option.swift
+++ b/Sources/ArgumentParser/Parsable Properties/Option.swift
@@ -31,7 +31,7 @@
///
/// mutating func run() {
/// print("\(greeting) \(name)!")
-/// if let age = age {
+/// if let age {
/// print("Congrats on making it to the ripe old age of \(age)!")
/// }
/// }
@@ -226,11 +226,11 @@ public struct ArrayParsingStrategy: Hashable {
/// through the terminator `--`. That is the more common approach. For example:
/// ```swift
/// struct Options: ParsableArguments {
- /// @Option var name: String
+ /// @Option var title: String
/// @Argument var remainder: [String]
/// }
/// ```
- /// would parse the input `--name Foo -- Bar --baz` such that the `remainder`
+ /// would parse the input `--title Foo -- Bar --baz` such that the `remainder`
/// would hold the value `["Bar", "--baz"]`.
public static var remaining: ArrayParsingStrategy {
self.init(base: .allRemainingInput)
@@ -241,20 +241,25 @@ extension ArrayParsingStrategy: Sendable { }
// MARK: - @Option T: ExpressibleByArgument Initializers
extension Option where Value: ExpressibleByArgument {
- /// Creates a property with a default value provided by standard Swift default value syntax.
+ /// Creates a property with a default value that reads its value from a
+ /// labeled option.
+ ///
+ /// This initializer is used when you declare an `@Option`-attributed property
+ /// that has an `ExpressibleByArgument` type, providing a default value:
///
- /// This method is called to initialize an `Option` with a default value such as:
/// ```swift
- /// @Option var foo: String = "bar"
+ /// @Option var title: String = "
"
/// ```
///
/// - Parameters:
/// - wrappedValue: A default value to use for this property, provided
- /// implicitly by the compiler during property wrapper initialization.
- /// - name: A specification for what names are allowed for this flag.
- /// - parsingStrategy: The behavior to use when looking for this option's value.
+ /// implicitly by the compiler during property wrapper initialization.
+ /// - name: A specification for what names are allowed for this option.
+ /// - parsingStrategy: The behavior to use when looking for this option's
+ /// value.
/// - help: Information about how to use this option.
- /// - completion: Kind of completion provided to the user for this option.
+ /// - completion: The type of command-line completion provided for this
+ /// option.
public init(
wrappedValue: Value,
name: NameSpecification = .long,
@@ -294,18 +299,22 @@ extension Option where Value: ExpressibleByArgument {
completion: completion)
}
- /// Creates a property with no default value.
+ /// Creates a required property that reads its value from a labeled option.
+ ///
+ /// This initializer is used when you declare an `@Option`-attributed property
+ /// that has an `ExpressibleByArgument` type, but without a default value:
///
- /// This method is called to initialize an `Option` without a default value such as:
/// ```swift
- /// @Option var foo: String
+ /// @Option var title: String
/// ```
///
/// - Parameters:
- /// - name: A specification for what names are allowed for this flag.
- /// - parsingStrategy: The behavior to use when looking for this option's value.
+ /// - name: A specification for what names are allowed for this option.
+ /// - parsingStrategy: The behavior to use when looking for this option's
+ /// value.
/// - help: Information about how to use this option.
- /// - completion: Kind of completion provided to the user for this option.
+ /// - completion: The type of command-line completion provided for this
+ /// option.
public init(
name: NameSpecification = .long,
parsing parsingStrategy: SingleValueParsingStrategy = .next,
@@ -329,22 +338,28 @@ extension Option where Value: ExpressibleByArgument {
// MARK: - @Option T Initializers
extension Option {
- /// Creates a property with a default value provided by standard Swift default value syntax.
+ /// Creates a property with a default value that reads its value from a
+ /// labeled option, parsing with the given closure.
+ ///
+ /// This initializer is used when you declare an `@Option`-attributed property
+ /// with a transform closure and a default value:
///
- /// This method is called to initialize an `Option` with a default value such as:
/// ```swift
- /// @Option var foo: String = "bar"
+ /// @Option(transform: { $0.first ?? " " })
+ /// var char: Character = "_"
/// ```
///
/// - Parameters:
- /// - wrappedValue: A default value to use for this property, provided
- /// implicitly by the compiler during property wrapper initialization.
- /// - name: A specification for what names are allowed for this flag.
- /// - parsingStrategy: The behavior to use when looking for this option's value.
+ /// - wrappedValue: The default value to use for this property, provided
+ /// implicitly by the compiler during property wrapper initialization.
+ /// - name: A specification for what names are allowed for this option.
+ /// - parsingStrategy: The behavior to use when looking for this option's
+ /// value.
/// - help: Information about how to use this option.
- /// - completion: Kind of completion provided to the user for this option.
+ /// - completion: The type of command-line completion provided for this
+ /// option.
/// - transform: A closure that converts a string into this property's
- /// element type or throws an error.
+ /// type, or else throws an error.
@preconcurrency
public init(
wrappedValue: Value,
@@ -369,19 +384,28 @@ extension Option {
})
}
- /// Creates a property with no default value.
+ /// Creates a required property that reads its value from a labeled option,
+ /// parsing with the given closure.
+ ///
+ /// This initializer is used when you declare an `@Option`-attributed property
+ /// with a transform closure and without a default value:
///
- /// This method is called to initialize an `Option` without a default value such as:
/// ```swift
- /// @Option var foo: String
+ /// @Option(transform: { $0.first ?? " " })
+ /// var char: Character
/// ```
///
/// - Parameters:
- /// - name: A specification for what names are allowed for this flag.
- /// - parsingStrategy: The behavior to use when looking for this option's value.
+ /// - name: A specification for what names are allowed for this option.
+ /// - parsingStrategy: The behavior to use when looking for this option's
+ /// value.
/// - help: Information about how to use this option.
- /// - completion: Kind of completion provided to the user for this option.
+ /// - completion: The type of command-line completion provided for this
+ /// option.
+ /// - transform: A closure that converts a string into this property's
+ /// type, or else throws an error.
@preconcurrency
+ @_disfavoredOverload
public init(
name: NameSpecification = .long,
parsing parsingStrategy: SingleValueParsingStrategy = .next,
@@ -407,16 +431,23 @@ extension Option {
// MARK: - @Option Optional Initializers
extension Option {
+ /// Creates an optional property that reads its value from a labeled option,
+ /// with an explicit `nil` default.
+ ///
/// This initializer allows a user to provide a `nil` default value for an
- /// optional `@Option`-marked property without allowing a non-`nil` default
- /// value.
+ /// optional `@Option`-marked property:
+ ///
+ /// ```swift
+ /// @Option var count: Int? = nil
+ /// ```
///
/// - Parameters:
- /// - name: A specification for what names are allowed for this flag.
+ /// - name: A specification for what names are allowed for this option.
/// - parsingStrategy: The behavior to use when looking for this option's
/// value.
/// - help: Information about how to use this option.
- /// - completion: Kind of completion provided to the user for this option.
+ /// - completion: The type of command-line completion provided for this
+ /// option.
public init(
wrappedValue _value: _OptionalNilComparisonType,
name: NameSpecification = .long,
@@ -463,18 +494,22 @@ extension Option {
})
}
- /// Creates a property that reads its value from a labeled option.
+ /// Creates an optional property that reads its value from a labeled option.
///
- /// If the property has an `Optional` type, or you provide a non-`nil`
- /// value for the `initial` parameter, specifying this option is not
- /// required.
+ /// This initializer is used when you declare an `@Option`-attributed property
+ /// with an optional type and no default value:
+ ///
+ /// ```swift
+ /// @Option var count: Int?
+ /// ```
///
/// - Parameters:
- /// - name: A specification for what names are allowed for this flag.
+ /// - name: A specification for what names are allowed for this option.
/// - parsingStrategy: The behavior to use when looking for this option's
/// value.
/// - help: Information about how to use this option.
- /// - completion: Kind of completion provided to the user for this option.
+ /// - completion: The type of command-line completion provided for this
+ /// option.
public init(
name: NameSpecification = .long,
parsing parsingStrategy: SingleValueParsingStrategy = .next,
@@ -498,24 +533,28 @@ extension Option {
// MARK: - @Option Optional Initializers
extension Option {
- /// Creates a property with a default value provided by standard Swift default
- /// value syntax, parsing with the given closure.
+ /// Creates an optional property that reads its value from a labeled option,
+ /// parsing with the given closure, with an explicit `nil` default.
+ ///
+ /// This initializer is used when you declare an `@Option`-attributed property
+ /// with a transform closure and with a default value of `nil`:
///
- /// This method is called to initialize an `Option` with a default value such as:
/// ```swift
- /// @Option(transform: baz)
- /// var foo: String = "bar"
+ /// @Option(transform: { $0.first ?? " " })
+ /// var char: Character? = nil
/// ```
///
/// - Parameters:
/// - wrappedValue: A default value to use for this property, provided
- /// implicitly by the compiler during property wrapper initialization.
- /// - name: A specification for what names are allowed for this flag.
- /// - parsingStrategy: The behavior to use when looking for this option's value.
+ /// implicitly by the compiler during property wrapper initialization.
+ /// - name: A specification for what names are allowed for this option.
+ /// - parsingStrategy: The behavior to use when looking for this option's
+ /// value.
/// - help: Information about how to use this option.
- /// - completion: Kind of completion provided to the user for this option.
- /// - transform: A closure that converts a string into this property's type
- /// or throws an error.
+ /// - completion: The type of command-line completion provided for this
+ /// option.
+ /// - transform: A closure that converts a string into this property's
+ /// type, or else throws an error.
@preconcurrency
public init(
wrappedValue _value: _OptionalNilComparisonType,
@@ -568,20 +607,26 @@ extension Option {
})
}
- /// Creates a property with no default value, parsing with the given closure.
+ /// Creates an optional property that reads its value from a labeled option,
+ /// parsing with the given closure.
+ ///
+ /// This initializer is used when you declare an `@Option`-attributed property
+ /// with a transform closure and without a default value:
///
- /// This method is called to initialize an `Option` with no default value such as:
/// ```swift
- /// @Option(transform: baz)
- /// var foo: String
+ /// @Option(transform: { $0.first ?? " " })
+ /// var char: Character?
/// ```
///
/// - Parameters:
- /// - name: A specification for what names are allowed for this flag.
- /// - parsingStrategy: The behavior to use when looking for this option's value.
+ /// - name: A specification for what names are allowed for this option.
+ /// - parsingStrategy: The behavior to use when looking for this option's
+ /// value.
/// - help: Information about how to use this option.
- /// - completion: Kind of completion provided to the user for this option.
- /// - transform: A closure that converts a string into this property's type or throws an error.
+ /// - completion: The type of command-line completion provided for this
+ /// option.
+ /// - transform: A closure that converts a string into this property's
+ /// type, or else throws an error.
@preconcurrency
public init(
name: NameSpecification = .long,
@@ -608,16 +653,30 @@ extension Option {
// MARK: - @Option Array Initializers
extension Option {
- /// Creates an array property that reads its values from zero or more
- /// labeled options.
+ /// Creates an array property that reads its values from zero or
+ /// more labeled options.
+ ///
+ /// This initializer is used when you declare an `@Option`-attributed array
+ /// property with a default value:
+ ///
+ /// ```swift
+ /// @Option(name: .customLong("char"))
+ /// var chars: [Character] = []
+ /// ```
///
/// - Parameters:
- /// - name: A specification for what names are allowed for this flag.
- /// - initial: A default value to use for this property.
- /// - parsingStrategy: The behavior to use when parsing multiple values
- /// from the command-line arguments.
+ /// - wrappedValue: A default value to use for this property, provided
+ /// implicitly by the compiler during property wrapper initialization.
+ /// If this initial value is non-empty, elements passed from the command
+ /// line are appended to the original contents.
+ /// - name: A specification for what names are allowed for this option.
+ /// - parsingStrategy: The behavior to use when parsing the elements for
+ /// this option.
/// - help: Information about how to use this option.
- /// - completion: Kind of completion provided to the user for this option.
+ /// - completion: The type of command-line completion provided for this
+ /// option.
+ /// - transform: A closure that converts a string into this property's
+ /// element type, or else throws an error.
public init(
wrappedValue: Array,
name: NameSpecification = .long,
@@ -639,19 +698,24 @@ extension Option {
})
}
- /// Creates an array property with no default value that reads its values from zero or more labeled options.
+ /// Creates a required array property that reads its values from zero or
+ /// more labeled options.
+ ///
+ /// This initializer is used when you declare an `@Option`-attributed array
+ /// property without a default value:
///
- /// This method is called to initialize an array `Option` with no default value such as:
/// ```swift
- /// @Option()
- /// var foo: [String]
+ /// @Option(name: .customLong("char"))
+ /// var chars: [Character]
/// ```
///
/// - Parameters:
- /// - name: A specification for what names are allowed for this flag.
- /// - parsingStrategy: The behavior to use when parsing multiple values from the command-line arguments.
+ /// - name: A specification for what names are allowed for this option.
+ /// - parsingStrategy: The behavior to use when parsing the elements for
+ /// this option.
/// - help: Information about how to use this option.
- /// - completion: Kind of completion provided to the user for this option.
+ /// - completion: The type of command-line completion provided for this
+ /// option.
public init(
name: NameSpecification = .long,
parsing parsingStrategy: ArrayParsingStrategy = .singleValue,
@@ -675,22 +739,30 @@ extension Option {
// MARK: - @Option Array Initializers
extension Option {
- /// Creates an array property that reads its values from zero or more
- /// labeled options, parsing with the given closure.
+ /// Creates an array property that reads its values from zero or
+ /// more labeled options, parsing each element with the given closure.
///
- /// This property defaults to an empty array if the `initial` parameter
- /// is not specified.
+ /// This initializer is used when you declare an `@Option`-attributed array
+ /// property with a transform closure and a default value:
+ ///
+ /// ```swift
+ /// @Option(name: .customLong("char"), transform: { $0.first ?? " " })
+ /// var chars: [Character] = []
+ /// ```
///
/// - Parameters:
- /// - name: A specification for what names are allowed for this flag.
- /// - initial: A default value to use for this property. If `initial` is
- /// `nil`, this option defaults to an empty array.
- /// - parsingStrategy: The behavior to use when parsing multiple values
- /// from the command-line arguments.
+ /// - wrappedValue: A default value to use for this property, provided
+ /// implicitly by the compiler during property wrapper initialization.
+ /// If this initial value is non-empty, elements passed from the command
+ /// line are appended to the original contents.
+ /// - name: A specification for what names are allowed for this option.
+ /// - parsingStrategy: The behavior to use when parsing the elements for
+ /// this option.
/// - help: Information about how to use this option.
- /// - completion: Kind of completion provided to the user for this option.
+ /// - completion: The type of command-line completion provided for this
+ /// option.
/// - transform: A closure that converts a string into this property's
- /// element type or throws an error.
+ /// element type, or else throws an error.
@preconcurrency
public init(
wrappedValue: Array,
@@ -715,23 +787,26 @@ extension Option {
})
}
- /// Creates an array property with no default value that reads its values from
- /// zero or more labeled options, parsing each element with the given closure.
+ /// Creates a required array property that reads its values from zero or
+ /// more labeled options, parsing each element with the given closure.
+ ///
+ /// This initializer is used when you declare an `@Option`-attributed array
+ /// property with a transform closure and without a default value:
///
- /// This method is called to initialize an array `Option` with no default value such as:
/// ```swift
- /// @Option(transform: baz)
- /// var foo: [String]
+ /// @Option(name: .customLong("char"), transform: { $0.first ?? " " })
+ /// var chars: [Character]
/// ```
///
/// - Parameters:
- /// - name: A specification for what names are allowed for this flag.
- /// - parsingStrategy: The behavior to use when parsing multiple values from
- /// the command-line arguments.
+ /// - name: A specification for what names are allowed for this option.
+ /// - parsingStrategy: The behavior to use when parsing the elements for
+ /// this option.
/// - help: Information about how to use this option.
- /// - completion: Kind of completion provided to the user for this option.
+ /// - completion: The type of command-line completion provided for this
+ /// option.
/// - transform: A closure that converts a string into this property's
- /// element type or throws an error.
+ /// element type, or else throws an error.
@preconcurrency
public init(
name: NameSpecification = .long,
diff --git a/Tests/ArgumentParserEndToEndTests/OptionalEndToEndTests.swift b/Tests/ArgumentParserEndToEndTests/OptionalEndToEndTests.swift
index cbb3b830..9d941554 100644
--- a/Tests/ArgumentParserEndToEndTests/OptionalEndToEndTests.swift
+++ b/Tests/ArgumentParserEndToEndTests/OptionalEndToEndTests.swift
@@ -206,3 +206,29 @@ extension OptionalEndToEndTests {
XCTAssertThrowsError(try Bar.parse(["-f", "--name", "A"]))
}
}
+
+extension OptionalEndToEndTests {
+ // Compilation test: https://github.com/apple/swift-argument-parser/issues/618
+ private struct Command: ParsableCommand {
+ struct MyError: Error {}
+ struct Foo {
+ init?(string: String) { return nil }
+ }
+
+ @Option(transform: {
+ guard let foo = Foo(string: $0) else {
+ throw MyError()
+ }
+ return foo
+ })
+ var testOption: Foo?
+
+ @Argument(transform: {
+ guard let foo = Foo(string: $0) else {
+ throw MyError()
+ }
+ return foo
+ })
+ var testArgument: Foo?
+ }
+}