1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
//! Running the command a line selected.
//!
//! Parsing gives a tree of types: a struct of the program's flags, holding an
//! enum of its subcommands, each holding a struct of its own. What the
//! program does next is nearly always the same: find the variant that was
//! selected and call the code that carries it out. [`Run`] is that call, and
//! `#[arg(run)]` on a `Subcommand` enum writes the `match` that makes it.
//!
//! Each command implements the trait, in a file of its own if it likes:
//!
//! use winnow_args::run::Run;
//! use winnow_args::{Args, Subcommand};
//!
//! #[derive(Args)]
//! struct Cli {
//! #[arg(short, long, global)]
//! verbose: bool,
//! #[arg(subcommand)]
//! command: Command,
//! }
//!
//! #[derive(Subcommand)]
//! #[arg(run)]
//! enum Command {
//! Add(Add),
//! Remove(Remove),
//! }
//!
//! #[derive(Args)]
//! struct Add {
//! #[arg(positional)]
//! name: String,
//! }
//!
//! #[derive(Args)]
//! struct Remove {
//! #[arg(positional)]
//! name: String,
//! }
//!
//! /// What every command is handed: here, the flags of the program.
//! struct Context {
//! verbose: bool,
//! }
//!
//! impl Run<&Context> for Add {
//! type Output = String;
//!
//! fn run(self, context: &Context) -> String {
//! match context.verbose {
//! true => format!("adding {}, at length", self.name),
//! false => format!("adding {}", self.name),
//! }
//! }
//! }
//!
//! impl Run<&Context> for Remove {
//! type Output = String;
//!
//! fn run(self, _: &Context) -> String {
//! format!("removing {}", self.name)
//! }
//! }
//!
//! let cli = Cli::parse_from(["-v", "add", "x"])?;
//! let context = Context { verbose: cli.verbose };
//! assert_eq!(cli.command.run(&context), "adding x, at length");
//! # Ok::<(), winnow_args::Error>(())
//! ```
//!
//! The context is whatever the commands share: a reference to the parsed
//! program, a connection, nothing at all (`()`, the default). The enum
//! implements the trait for every context all of its commands take, so a
//! struct that holds a nested enum of subcommands implements it by calling
//! `self.command.run(context)`, and the nesting runs all the way down.
//!
//! [`RunAsync`] and `#[arg(run_async)]` are the same for commands that are
//! awaited.
//!
//! None of this is on the path of a parse: it is a `match` in the program,
//! written by the derive rather than by hand.
/// A command that can be carried out, given `C`.
/// A command that is awaited: [`Run`], as a future.
///
/// An implementation writes `async fn run_async(self, context: C)`. The
/// signature here is `-> impl Future` so that the trait implies no `Send`
/// bound either way: whether a command's future is `Send` is decided by what
/// the command does.