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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
//! # Using the library in derive style
//! # About examples
//!
//! Most of the examples omit adding doc comments to the fields, to keep things clearer, you should do
//! that when possible for better end user experience. Don't forget to add `#[bpaf(options)]` for a top level
//! structure that defines the option parser itself.
//!
//! ```rust
//! # use bpaf::*;
//! #[derive(Debug, Clone, Bpaf)]
//! #[bpaf(options)] // <- important bit
//! struct Config {
//! /// number used by the program
//! number: u32,
//! }
//! ```
//!
//! In addition to examples in the documentation there's a bunch more in the github repository:
//! <https://github.com/pacak/bpaf/tree/master/examples>
//! # Recommended reading order
//!
//! Combinatoric and derive APIs share the documentation and most of the names, recommended reading order:
//! 1. [`construct!`] - what combinations are
//! 2. [`NamedArg`], [`positional`] and [`command`] - on consuming data
//! 3. [`Parser`] - on transforming the data
//! 4. [`OptionParser`] - on running the result
//! # Getting started
//!
//! 1. To use derive style API you need to enable `"derive"` feature for `bpaf`, **by default it's not
//! enabled**.
//!
//! 2. Define primitive parsers if you want to use any. While it's possible to define most of them
//! in derive style - doing complex parsing or validation is often easier in combinatoric style
//!
//! 3. Define types used to derive parsers, structs correspond to *AND* combination and require for
//! all the fields to have a value, enums to *OR* combinations and require (and consume) all the
//! values for one branch only.
//!
//! 4. Add annotations to the top level of a struct if needed, there's several to choose from and
//! you can specify several of them. For this annotation ordering doesn't matter.
//!
//! - ### Generated function name: `generate`
//!
//! Unlike usual derive macro `bpaf_derive` generates a function with a name
//! derived from a struct name by transforming it from `CamelCase` to `snake_case`. `generate`
//! annotation allows to override a name for the function
//!
//! ```rust
//! # use bpaf::*;
//! #[derive(Debug, Clone, Bpaf)]
//! #[bpaf(generate(make_config))] // function name is now make_config()
//! pub struct Config {
//! pub flag: bool
//! }
//! ```
//!
//! - ### Generated function visibility: `private`
//!
//! By default `bpaf` uses the same visibility as the datatype,
//! `private` makes it module private:
//!
//! ```rust
//! # use bpaf::*;
//! #[derive(Debug, Clone, Bpaf)]
//! #[bpaf(private)] // config() is now module private
//! pub struct Config {
//! pub flag: bool
//! }
//! ```
//!
//! - ### Generated function types: `command`, `options`
//!
//! By default `bpaf_derive` would generate a function that generates a regular [`Parser`]
//! it's possible instead to turn it into a
//! [`command`] with `command` annotation or into a top level [`OptionParser`] with `options`
//! annotation.
//! Those annotations are mutually exclusive. `options` annotation takes an optional argument
//! to use for [`cargo_helper`], `command` annotation takes an optional argument to
//! override a command name.
//!
//! ```rust
//! # use bpaf::*;
//! #[derive(Debug, Clone, Bpaf)]
//! pub struct Flag { // impl Parser by default
//! pub flag: bool
//! }
//!
//! #[derive(Debug, Clone, Bpaf)]
//! #[bpaf(command)]
//! pub struct Make { // generates a command "make"
//! pub level: u32,
//! }
//!
//!
//! #[derive(Debug, Clone, Bpaf)]
//! #[bpaf(options)] // config() is now OptionParser
//! pub struct Config {
//! pub flag: bool
//! }
//! ```
//!
//! - ### Specify version for generated command: `version`
//!
//! By default `bpaf_derive` embedds no version information. With `version` with no argument
//! results in using version from `CARGO_PKG_VERSION` env variable (specified by cargo on
//! compile time, usually originates from `Cargo.toml`), `version` with argument results in
//! using tht specific version - can be string literal or static string expression.
//! Only makes sense for `command` and `options` annotations. For more information see
//! [`version`](OptionParser::version).
//!
//! ```rust
//! # use bpaf::*;
//! #[derive(Debug, Clone, Bpaf)]
//! #[bpaf(options, version("3.1415"))] // --version is now 3.1415
//! pub struct Config {
//! pub flag: bool
//! }
//! ```
//!
//! - ### Fallback value if all parsers fails: `fallback`
//!
//! You can add a fallback value to use if all the values required are missing.
//! See [`req_flag`](NamedArg::req_flag) examples.
//!
//! 5. Add annotations to individual fields. Structure for annotation for individual fields
//! is similar to how you would write the same code with combinatoric API with exception
//! of `external` and usually looks something like this:
//!
//! `((<naming> <consumer>) | <external>) <postprocessing>`
//!
//! - `naming` section corresponds to [`short`], [`long`] and [`env`](env()). `short` takes an optional
//! character literal as a parameter, `long` takes an optional string, `env` takes an
//! expression of type `&'static str` as a parameter - could be a string literal or a
//! constant.
//!
//! + If parameter for `short`/`long` is parameter isn't present it's derived from the field
//! name: first character and a whole name respectively.
//!
//! + If either of `short` or `long` is present - `bpaf_derive` would not add the other one.
//!
//! + If neither is present - `bpaf_derive` would add a `long` one.
//!
//! ```rust
//! # use bpaf::*;
//! const DB: &str = "top_secret_database";
//!
//! #[derive(Debug, Clone, Bpaf)]
//! pub struct Config {
//! pub flag_1: bool, // no annotation: --flag_1
//!
//! #[bpaf(short)]
//! pub flag_2: bool, // explicit short suppresses long: -f
//!
//! #[bpaf(short('z'))]
//! pub flag_3: bool, // explicit short with custom letter: -z
//!
//! #[bpaf(short, long)]
//! pub deposit: bool, // explicit short and long: -d --deposit
//!
//! #[bpaf(env(DB))]
//! pub database: String, // --database + env variable from DB constant
//!
//! #[bpaf(env("USER"))] // --user + env variable "USER"
//! pub user: String,
//! }
//! ```
//!
//! - `consumer` section corresponds to [`argument`](NamedArg::argument), [`positional`],
//! [`flag`](NamedArg::flag), [`switch`](NamedArg::switch) and [`any`].
//!
//! + With no consumer annotations `bpaf_derive` parses tuple structs (`struct Config(String)`)
//! as positional items, but it's possible to override it by giving it a name:
//!
//! ```rust
//! # use bpaf::*;
//! # use std::path::PathBuf;
//! #[derive(Debug, Clone, Bpaf)]
//! struct Opt(PathBuf); // stays positional
//!
//! #[derive(Debug, Clone, Bpaf)]
//! struct Config(#[bpaf(long("input"))] PathBuf); // turns into a named argument
//! ```
//!
//! + `bpaf_derive` handles fields of type `Option<Foo>` with [`optional`](Parser::optional)
//! and `Vec<Foo>` with [`many`](Parser::many), see `postprocessing` for more details.
//!
//! + `bpaf_derive` handles `bool` fields with [`switch`](NamedArg::switch),
//! `()` with [`req_flag`](NamedArg::req_flag), [`OsString`] and [`PathBuf`] are parsed from
//! `OsString` and anything else with [`FromStr`] trait. See documentation for
//! [`argument`](NamedArg::argument) and [`positional`] for more details.
//!
//! - If `external` is present - it usually serves function of `naming` and `consumer`, allowing
//! more for `postprocessing` annotations after it. Takes an optional parameter - a function
//! name to call, if not present - `bpaf_derive` uses field name for this purpose.
//! Functions should return impl [`Parser`] and you can either declare them manually
//! or derive with `Bpaf` macro.
//!
//! ```rust
//! # use bpaf::*;
//! fn verbosity() -> impl Parser<usize> {
//! short('v')
//! .help("vebosity, can specify multiple times")
//! .req_flag(())
//! .many()
//! .map(|x| x.len())
//! }
//!
//! #[derive(Debug, Clone, Bpaf)]
//! pub struct Username {
//! pub user: String
//! }
//!
//! #[derive(Debug, Clone, Bpaf)]
//! pub struct Config {
//! #[bpaf(external)]
//! pub verbosity: usize, // implicit name - "verbosity"
//!
//! #[bpaf(external(username))]
//! pub custom_user: Username, // explicit name - "username"
//! }
//! ```
//!
//! - `postprocessing` - various methods from [`Parser`] trait, order matters, most of them are
//! taken literal, see documentation for the trait for more details. `bpaf_derive` automatically
//! uses [`many`](Parser::many) and [`optional`](Parser::optional) to handle `Vec<T>` and
//! `Option<T>` fields respectively.
//!
//! Any operation that can change the type (such as [`parse`](Parser::parse) or [`map`](Parser::map))
//! for disables this logic for the field and also requires to specify the consumer:
//! ```rust
//! # use bpaf::*;
//! #[derive(Debug, Clone, Bpaf)]
//! struct Options {
//! #[bpaf(argument::<u32>("NUM"), many)]
//! numbers: Vec<u32>
//! }
//! ```
//!
//! - field-less enum variants obey slightly different set of rules, see
//! [`req_flag`](NamedArg::req_flag) for more details.
//!
//! - any constructor in `enum` can have `skip` annotation - `bpaf_derive`
//! would ignore them when generating code:
//! ```rust
//! # use bpaf::*;
//! #[derive(Debug, Clone, Bpaf)]
//! enum Decision {
//! Yes,
//! No,
//! #[bpaf(skip)]
//! Maybe
//! }
//!
//! ```
//!
//! 6. Add documentation for help messages.
//! `bpaf_derive` generates help messages from doc comments, it skips single empty lines and stops
//! processing after double empty line:
//!
//! ```rust
//! # use bpaf::*;
//! #[derive(Debug, Clone, Bpaf)]
//! pub struct Username {
//! /// this is a part of a help message
//! ///
//! /// so is this
//! ///
//! ///
//! /// but this isn't
//! pub user: String
//! }
//! ```
//!
//! 7. Add [`check_invariants`](OptionParser::check_invariants) to your test code.
use crate::;
use ;
use crate cargo_helper;