You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In some use cases, there is a need to have an option argument behave
like a flag.
This change introduced 4 new intialiazers to `Option` that accept a
`defaultAsFlag` value.
With the following usage:
```swift
struct Example: ParsableCommand {
@option(defaultAsFlag: "default", help: "Set output format.")
var format: String?
func run() {
print("Format: \(format ?? "none")")
}
}
```
The `defaultAsFlag` parameter creates a hybrid that supports both patterns:
- **Flag behavior**: `--format` (sets format to "default")
- **Option behavior**: `--format json` (sets format to "json")
- **No usage**: format remains `nil`
As a user of the command line tool, the `--help` output clearly distinguishes
between the the hybrid and regular usages.
```
OPTIONS:
--format [<format>] Set output format. (default as flag: default)
````
Note the `(default as flag: ...)` text instead of regular `(default: ...)`,
and the optional value syntax `[<value>]` instead of required `<value>`.
Fixes: #829
Copy file name to clipboardExpand all lines: Sources/ArgumentParser/Documentation.docc/Articles/DeclaringArguments.md
+79-2Lines changed: 79 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -81,7 +81,7 @@ struct Lucky: ParsableCommand {
81
81
```
82
82
83
83
```
84
-
% lucky
84
+
% lucky
85
85
Your lucky numbers are:
86
86
7 14 21
87
87
% lucky 1 2 3
@@ -327,6 +327,83 @@ If a default is not specified, the user must provide a value for that argument/o
327
327
You must also always specify a default of `false` for a non-optional `Bool` flag, as in the example above. This makes the behavior consistent with both normal Swift properties (which either must be explicitly initialized or optional to initialize a `struct`/`class` containing them) and the other property types.
328
328
329
329
330
+
### Creating hybrid flag/option behavior with defaultAsFlag
331
+
332
+
The `defaultAsFlag` parameter allows you to create options that can work both as flags (without values) and as options (with values). This provides flexible command-line interfaces where users can choose between concise flag usage or explicit value specification.
333
+
334
+
```swift
335
+
structExample: ParsableCommand {
336
+
@Option(defaultAsFlag:"json", help:"Set the export format.")
337
+
var export: String?
338
+
339
+
funcrun() {
340
+
print("Export: \(format ??"<don't export>")")
341
+
}
342
+
}
343
+
```
344
+
345
+
**Command-line behavior:**
346
+
```
347
+
% example # export = nil
348
+
% example --export # export = "json"
349
+
% example --export yaml # format = "yaml"
350
+
```
351
+
352
+
The `defaultAsFlag` parameter creates a hybrid that supports both patterns:
353
+
-**Flag behavior**: `--export` (sets format to "json")
354
+
-**Option behavior**: `--export yaml` (sets format to "yaml")
355
+
-**No usage**: `export` remains `nil`
356
+
357
+
#### Type requirements
358
+
359
+
- The property **must** be optional (`T?`)
360
+
- The `defaultAsFlag` value must be of the unwrapped type (`T`)
361
+
- All standard `ExpressibleByArgument` types are supported (String, Int, Bool, Double, etc.)
362
+
363
+
#### Advanced usage
364
+
365
+
You can combine `defaultAsFlag` with transform functions:
DefaultAsFlag options show special help formatting to distinguish them from regular defaults:
385
+
386
+
```
387
+
OPTIONS:
388
+
--format [<format>] Set output format. (default as flag: json)
389
+
--port [<port>] Server port. (default as flag: 8080)
390
+
```
391
+
392
+
Note the `(default as flag: ...)` text instead of regular `(default: ...)`, and the optional value syntax `[<value>]` instead of required `<value>`.
393
+
394
+
#### Value detection
395
+
396
+
The parser determines whether a value follows the option:
397
+
398
+
1.**Next argument is a value** if it doesn't start with `-` and isn't another known option
399
+
2.**No value available**: Use the `defaultAsFlag` value
400
+
3.**Explicit value provided**: Parse and use that value
401
+
402
+
This works with parsing strategies `.next` and `.scanningForValue`. The `.unconditional` parsing strategy defeats the purpose by always requiring a value.
403
+
404
+
For complete examples and API reference, see the [`default-as-flag`](https://github.com/apple/swift-argument-parser/tree/main/Examples/default-as-flag) example.
405
+
406
+
330
407
### Specifying a parsing strategy
331
408
332
409
When parsing a list of command-line inputs, `ArgumentParser` distinguishes between dash-prefixed keys and un-prefixed values. When looking for the value for a key, only an un-prefixed value will be selected by default.
@@ -479,7 +556,7 @@ When appropriate, you can process supported arguments and ignore unknown ones by
0 commit comments