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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
//! Derive Api for `blarg` configuration.
//!
//! ### Getting Started
//! Use the derive Api by starting with a parameter struct `S` instrumented with `#[derive(BlargParser)]`.
//! This will generate a function `S::blarg_parse() -> S` which parses the Cli parameters fitting `S`.
//! `blarg` will do its best to infer the intended Cli from the parameter structure `S`.
//!
//! This page includes a few demos on using the derive Api.
//! More examples are outlined in [the source](https://github.com/sawatzkylindsey/blarg/tree/main/examples).
//!
//! ```no_run
//! ```
//!
//! This generates the following Cli program:
//! ```console
//! $ demo_derived -h
//! usage: demo_derived [-h] [--banana] [--daikon-root DAIKON_ROOT] APPLE CARROTS [...]
//! positional arguments:
//! APPLE type: usize
//! CARROTS [...] type: u32 initial: []
//! options:
//! -h, --help Show this help message and exit.
//! --banana
//! --daikon-root DAIKON_ROOT type: String
//! ```
//!
//!
//! ### Parser/SubParser Configuration
//! See the macro definition for details on configuring the [`BlargParser`] and [`BlargSubParser`].
//!
//! ### Parameter Configuration
//! The implicit Cli inference uses the following rules:
//! ```console
//! Type | Parameter
//! -----------------------------------
//! Option<T> | Parameter::option(Optional::new(..), ..)
//! Vec<T> | Parameter::argument(Collection::new(.., Nargs::AtLeastOne), ..)
//! HashSet<T> | Parameter::argument(Collection::new(.., Nargs::AtLeastOne), ..)
//! bool | Parameter::option(Switch::new(..), ..)
//! T | Parameter::argument(Scalar::new(..) , ..)
//! ```
//!
//! Notice, these implicit rules do not capture all possible `blarg` configurations.
//! Therefore, we provide the additional explicit configuration field attributes, which may be combined as necessary.
//! * `#[blarg(argument)]` or `#[blarg(option)]` to explicitly use `Parameter::argument(..)` or `Parameter::option(..)`, respectively.
//! Only one of these may be used on the same field.
//! * `#[blarg(short = C]` to explicitly set the short name for an option parameter.
//! `C` must be a char value (ex: `'c'`).
//! * `#[blarg(collection = N)]` to explicitly use `Collection::new(.., N)`, where `N` is the [Nargs](../enum.Nargs.html) variant.
//! This is useful both for non-`Vec`/`HashSet` [Collectable](../prelude/trait.Collectable.html) types, as well as to control the `Nargs` variant.
//! * `#[blarg(command = (Vi, Si), .., command = (Vj, Sj))]` to define sub-command [branches](../struct.CommandLineParser.html#method.branch) on the pairs `(Vi, Si), .., (Vj, Sj)`.
//! Each pair must be the variant `V*` and sub-parameter struct `S*` to configure.
//! `S*` must be instrumented with `#[blarg(BlargSubParser)]`, and follows the same configuration rules (both implicit and explicit) as a `BlargParser`.
//!
//! A partial example of these rules is provided as follows:
//! ```ignore
//! #[derive(Default, BlargParser)]
//! struct Parameters {
//! #[blarg(argument)]
//! quick: usize,
//! // the above generates:
//! // .add(Parameter::argument(Scalar::new(&mut parameters.quick), "quick"))
//!
//! #[blarg(option)]
//! brown: usize,
//! // the above generates:
//! // .add(Parameter::option(Scalar::new(&mut parameters.brown), "brown", None))
//!
//! #[blarg(option, short = 'f')]
//! fox: usize,
//! // the above generates:
//! // .add(Parameter::option(Scalar::new(&mut parameters.fox), "fox", Some('f')))
//!
//! #[blarg(collection = Nargs::Precisely(2))]
//! jumps: Pair<usize>,
//! // the above generates:
//! // .add(Parameter::argument(Collection::new(&mut parameters.jumps, Nargs::Precisely(2)), "jumps"))
//! // assumes: `impl<T> Collectable<T> for Pair<T>`
//!
//! #[blarg(command = (0, Sub0), command = (1, Sub1))]
//! over: usize,
//! // the above generates:
//! // .branch(Condition::new(Scalar::new(&mut parameters.over), "over"))
//! // .command(0, Sub0::setup_command) // assuming `Sub0` is instrumented with `BlargSubParser`
//! // .command(1, Sub1::setup_command) // assuming `Sub1` is instrumented with `BlargSubParser`
//! }
//!
//! #[derive(Default, BlargSubParser)]
//! struct Sub0 {
//! ..
//! }
//!
//! #[derive(Default, BlargSubParser)]
//! struct Sub1 {
//! ..
//! }
//! ```
//!
//! ### Help Messages
//! The previous implicit and explicit rules are sufficient to configure all possible `blarg` Cli semantics.
//! Additionally, the following field attributes may be used to configure the Cli help message.
//! * `#[blarg(help = "..")]` defines the help message for the parameter.
//! This value is passed directly via the "help" documentation mechanism ([parameter help](../struct.Parameter.html#method.help) or [condition help](../struct.Condition.html#method.help)).
//! * `#[blarg(choices)]` instructs `blarg` to use the choice function generated by instrumenting the enum struct with `#[derive(BlargChoices)]`.
//! See defining choices on a [parameter](../struct.Parameter.html#method.choice) or [condition](../struct.Condition.html#method.choice) for how this affects the Cli help message.
//! * `#[blarg(choices = F)]` instructs `blarg` to use the choice function `F`.
//! This has the same meaning as the previous point.
//!
//! The noted two `choices` attributes leverage functions of the signature `fn my_func(value: Parameter<T>) -> Parameter<T>`, where:
//! * `T` is the concrete type of the field under instrumentation.
//!
//! For example: `fn my_func(value: Parameter<usize>) -> Parameter<usize>`.
//! Notice, if `choices` is applied to a sub-command branching field (`#[blarg(command = ..)]`), then instead use `fn my_func(value: Condition<T>) -> Condition<T>`.
//!
//! A partial example of these rules is provided as follows:
//! ```ignore
//! #[derive(Default, BlargParser)]
//! struct Parameters {
//! #[blarg(help = "do something")]
//! lazy: usize,
//! // the above generates:
//! // .add(Parameter::argument(Scalar::new(&mut parameters.lazy), "lazy")
//! // .help("do something"))
//!
//! #[blarg(choices)]
//! dog: Enumeration,
//! // the above generates:
//! // .add(Enumeration::setup_choices(Parameter::argument(Scalar::new(&mut parameters.dog), "dog")))
//! // assumes: `Enumeration` is instrumented with `BlargChoices`
//!
//! #[blarg(choices = setup_choices)]
//! period: usize,
//! // the above generates:
//! // .add(setup_choices(Parameter::argument(Scalar::new(&mut parameters.period), "period")))
//! }
//!
//! /// My custom setup_choices fn.
//! fn setup_choices(value: Parameter<usize>) -> Parameter<usize> {
//! value.choice(0, "the 0th choice")
//! .choice(1, "the 1st choice")
//! .choice(2, "the 2nd choice")
//! }
//!
//! #[derive(BlargChoices)]
//! enum Enumeration {
//! ..
//! }
//! ```
//!
//! ### Choices
//! In the case of enums, simply instrument with `#[derive(BlargChoices)]` to automatically generate the setup function.
//! The enum may be configured with the following field attributes:
//! * `#[blarg(help = "..")]` defines the help message for the variant.
//! * `#[blarg(hidden)]` instructs `blarg` to hide the variant.
//!
//! For example:
//! ```ignore
//! #[derive(BlargChoices)]
//! enum Enumeration {
//! VariantA,
//! // the above generates:
//! // .choice(VariantA, "")
//!
//! #[blarg(help = "the variant B choice")]
//! VariantB,
//! // the above generates:
//! // .choice(VariantB, "the variant B choice")
//!
//! #[blarg(hidden)]
//! VariantC,
//! // the above does *not* instrument a `.choice(..)`
//! }
//! ```
pub use *;