clap_v3/
lib.rs

1// Copyright ⓒ 2015-2016 Kevin B. Knapp and [`clap-rs` contributors](https://github.com/kbknapp/clap-rs/blob/master/CONTRIBUTORS.md).
2// Licensed under the MIT license
3// (see LICENSE or <http://opensource.org/licenses/MIT>) All files in the project carrying such
4// notice may not be copied, modified, or distributed except according to those terms.
5
6//! `clap` is a simple-to-use, efficient, and full-featured library for parsing command line
7//! arguments and subcommands when writing console/terminal applications.
8//!
9//! ## About
10//!
11//! `clap` is used to parse *and validate* the string of command line arguments provided by the user
12//! at runtime. You provide the list of valid possibilities, and `clap` handles the rest. This means
13//! you focus on your *applications* functionality, and less on the parsing and validating of
14//! arguments.
15//!
16//! `clap` also provides the traditional version and help switches (or flags) 'for free' meaning
17//! automatically with no configuration. It does this by checking the list of valid possibilities you
18//! supplied and adding only the ones you haven't already defined. If you are using subcommands,
19//! `clap` will also auto-generate a `help` subcommand for you in addition to the traditional flags.
20//!
21//! Once `clap` parses the user provided string of arguments, it returns the matches along with any
22//! applicable values. If the user made an error or typo, `clap` informs them of the mistake and
23//! exits gracefully (or returns a `Result` type and allows you to perform any clean up prior to
24//! exit). Because of this, you can make reasonable assumptions in your code about the validity of
25//! the arguments.
26//!
27//!
28//! ## Quick Example
29//!
30//! The following examples show a quick example of some of the very basic functionality of `clap`.
31//! For more advanced usage, such as requirements, conflicts, groups, multiple values and
32//! occurrences see the [documentation](https://docs.rs/clap/), [examples/] directory of
33//! this repository or the [video tutorials].
34//!
35//! **NOTE:** All of these examples are functionally the same, but show different styles in which to
36//! use `clap`
37//!
38//! The first example shows a method that allows more advanced configuration options (not shown in
39//! this small example), or even dynamically generating arguments when desired. The downside is it's
40//! more verbose.
41//!
42//! ```no_run
43//! // (Full example with detailed comments in examples/01b_quick_example.rs)
44//! //
45//! // This example demonstrates clap's full 'builder pattern' style of creating arguments which is
46//! // more verbose, but allows easier editing, and at times more advanced options, or the possibility
47//! // to generate arguments dynamically.
48//! use clap::{Arg, App, };
49//!
50//! fn main() {
51//!     let matches = App::new("My Super Program")
52//!                           .version("1.0")
53//!                           .author("Kevin K. <kbknapp@gmail.com>")
54//!                           .about("Does awesome things")
55//!                           .arg(Arg::with_name("config")
56//!                                .short('c')
57//!                                .long("config")
58//!                                .value_name("FILE")
59//!                                .help("Sets a custom config file")
60//!                                .takes_value(true))
61//!                           .arg(Arg::with_name("INPUT")
62//!                                .help("Sets the input file to use")
63//!                                .required(true)
64//!                                .index(1))
65//!                           .arg(Arg::with_name("v")
66//!                                .short('v')
67//!                                .multiple(true)
68//!                                .help("Sets the level of verbosity"))
69//!                           .subcommand(App::new("test")
70//!                                       .about("controls testing features")
71//!                                       .version("1.3")
72//!                                       .author("Someone E. <someone_else@other.com>")
73//!                                       .arg(Arg::with_name("debug")
74//!                                           .short('d')
75//!                                           .help("print debug information verbosely")))
76//!                           .get_matches();
77//!
78//!     // Gets a value for config if supplied by user, or defaults to "default.conf"
79//!     let config = matches.value_of("config").unwrap_or("default.conf");
80//!     println!("Value for config: {}", config);
81//!
82//!     // Calling .unwrap() is safe here because "INPUT" is required (if "INPUT" wasn't
83//!     // required we could have used an 'if let' to conditionally get the value)
84//!     println!("Using input file: {}", matches.value_of("INPUT").unwrap());
85//!
86//!     // Vary the output based on how many times the user used the "verbose" flag
87//!     // (i.e. 'myprog -v -v -v' or 'myprog -vvv' vs 'myprog -v'
88//!     match matches.occurrences_of("v") {
89//!         0 => println!("No verbose info"),
90//!         1 => println!("Some verbose info"),
91//!         2 => println!("Tons of verbose info"),
92//!         3 | _ => println!("Don't be crazy"),
93//!     }
94//!
95//!     // You can handle information about subcommands by requesting their matches by name
96//!     // (as below), requesting just the name used, or both at the same time
97//!     if let Some(matches) = matches.subcommand_matches("test") {
98//!         if matches.is_present("debug") {
99//!             println!("Printing debug info...");
100//!         } else {
101//!             println!("Printing normally...");
102//!         }
103//!     }
104//!
105//!     // more program logic goes here...
106//! }
107//! ```
108//!
109//! The next example shows a far less verbose method, but sacrifices some of the advanced
110//! configuration options (not shown in this small example). This method also takes a *very* minor
111//! runtime penalty.
112//!
113//! ```no_run
114//! // (Full example with detailed comments in examples/01a_quick_example.rs)
115//! //
116//! // This example demonstrates clap's "usage strings" method of creating arguments
117//! // which is less verbose
118//! use clap::{Arg, App, };
119//!
120//! fn main() {
121//!     let matches = App::new("myapp")
122//!                           .version("1.0")
123//!                           .author("Kevin K. <kbknapp@gmail.com>")
124//!                           .about("Does awesome things")
125//!                           .arg("-c, --config=[FILE] 'Sets a custom config file'")
126//!                           .arg("<INPUT>              'Sets the input file to use'")
127//!                           .arg("-v...                'Sets the level of verbosity'")
128//!                           .subcommand(App::new("test")
129//!                                       .about("controls testing features")
130//!                                       .version("1.3")
131//!                                       .author("Someone E. <someone_else@other.com>")
132//!                                       .arg("-d, --debug 'Print debug information'"))
133//!                           .get_matches();
134//!
135//!     // Same as previous example...
136//! }
137//! ```
138//!
139//! This third method shows how you can use a YAML file to build your CLI and keep your Rust source
140//! tidy or support multiple localized translations by having different YAML files for each
141//! localization.
142//!
143//! First, create the `cli.yml` file to hold your CLI options, but it could be called anything we
144//! like:
145//!
146//! ```yaml
147//! name: myapp
148//! version: "1.0"
149//! author: Kevin K. <kbknapp@gmail.com>
150//! about: Does awesome things
151//! args:
152//!     - config:
153//!         short: c
154//!         long: config
155//!         value_name: FILE
156//!         help: Sets a custom config file
157//!         takes_value: true
158//!     - INPUT:
159//!         help: Sets the input file to use
160//!         required: true
161//!         index: 1
162//!     - verbose:
163//!         short: v
164//!         multiple: true
165//!         help: Sets the level of verbosity
166//! subcommands:
167//!     - test:
168//!         about: controls testing features
169//!         version: "1.3"
170//!         author: Someone E. <someone_else@other.com>
171//!         args:
172//!             - debug:
173//!                 short: d
174//!                 help: print debug information
175//! ```
176//!
177//! Since this feature requires additional dependencies that not everyone may want, it is *not*
178//! compiled in by default and we need to enable a feature flag in Cargo.toml:
179//!
180//! Simply change your `clap = "~2.27.0"` to `clap = {version = "~2.27.0", features = ["yaml"]}`.
181//!
182//! At last we create our `main.rs` file just like we would have with the previous two examples:
183//!
184//! ```ignore
185//! // (Full example with detailed comments in examples/17_yaml.rs)
186//! //
187//! // This example demonstrates clap's building from YAML style of creating arguments which is far
188//! // more clean, but takes a very small performance hit compared to the other two methods.
189//! use clap::App;
190//!
191//! fn main() {
192//!     // The YAML file is found relative to the current file, similar to how modules are found
193//!     let yaml = load_yaml!("cli.yml");
194//!     let matches = App::from_yaml(yaml).get_matches();
195//!
196//!     // Same as previous examples...
197//! }
198//! ```
199//!
200//! Finally there is a macro version, which is like a hybrid approach offering the speed of the
201//! builder pattern (the first example), but without all the verbosity.
202//!
203//! ```no_run
204//! use clap::clap_app;
205//! fn main() {
206//!     let matches = clap_app!(myapp =>
207//!         (version: "1.0")
208//!         (author: "Kevin K. <kbknapp@gmail.com>")
209//!         (about: "Does awesome things")
210//!         (@arg CONFIG: -c --config +takes_value "Sets a custom config file")
211//!         (@arg INPUT: +required "Sets the input file to use")
212//!         (@arg debug: -d ... "Sets the level of debugging information")
213//!         (@subcommand test =>
214//!             (about: "controls testing features")
215//!             (version: "1.3")
216//!             (author: "Someone E. <someone_else@other.com>")
217//!             (@arg verbose: -v --verbose "Print test information verbosely")
218//!         )
219//!     ).get_matches();
220//!
221//!     // Same as before...
222//! }
223//! ```
224//!
225//! If you were to compile any of the above programs and run them with the flag `--help` or `-h` (or
226//! `help` subcommand, since we defined `test` as a subcommand) the following would be output
227//!
228//! ```text
229//! $ myprog --help
230//! My Super Program 1.0
231//! Kevin K. <kbknapp@gmail.com>
232//! Does awesome things
233//!
234//! USAGE:
235//!     MyApp [FLAGS] [OPTIONS] <INPUT> [SUBCOMMAND]
236//!
237//! FLAGS:
238//!     -h, --help       Prints this message
239//!     -v               Sets the level of verbosity
240//!     -V, --version    Prints version information
241//!
242//! OPTIONS:
243//!     -c, --config <FILE>    Sets a custom config file
244//!
245//! ARGS:
246//!     INPUT    The input file to use
247//!
248//! SUBCOMMANDS:
249//!     help    Prints this message
250//!     test    Controls testing features
251//! ```
252//!
253//! **NOTE:** You could also run `myapp test --help` to see similar output and options for the
254//! `test` subcommand.
255//!
256//! ## Try it!
257//!
258//! ### Pre-Built Test
259//!
260//! To try out the pre-built example, use the following steps:
261//!
262//! * Clone the repository `$ git clone https://github.com/kbknapp/clap-rs && cd clap-rs/tests`
263//! * Compile the example `$ cargo build --release`
264//! * Run the help info `$ ./target/release/claptests --help`
265//! * Play with the arguments!
266//!
267//! ### BYOB (Build Your Own Binary)
268//!
269//! To test out `clap`'s default auto-generated help/version follow these steps:
270//!
271//! * Create a new cargo project `$ cargo new fake --bin && cd fake`
272//! * Add `clap` to your `Cargo.toml`
273//!
274//! ```toml
275//! [dependencies]
276//! clap = "2"
277//! ```
278//!
279//! * Add the following to your `src/main.rs`
280//!
281//! ```no_run
282//! use clap::App;
283//!
284//! fn main() {
285//!   App::new("fake").version("v1.0-beta").get_matches();
286//! }
287//! ```
288//!
289//! * Build your program `$ cargo build --release`
290//! * Run with help or version `$ ./target/release/fake --help` or `$ ./target/release/fake
291//! --version`
292//!
293//! ## Usage
294//!
295//! For full usage, add `clap` as a dependency in your `Cargo.toml` (it is **highly** recommended to
296//! use the `~major.minor.patch` style versions in your `Cargo.toml`, for more information see
297//! [Compatibility Policy](#compatibility-policy)) to use from crates.io:
298//!
299//! ```toml
300//! [dependencies]
301//! clap = "~2.27.0"
302//! ```
303//!
304//! Or get the latest changes from the master branch at github:
305//!
306//! ```toml
307//! [dependencies.clap]
308//! git = "https://github.com/kbknapp/clap-rs.git"
309//! ```
310//!
311//! Define a list of valid arguments for your program (see the
312//! [documentation](https://docs.rs/clap/) or [examples/] directory of this repo)
313//!
314//! Then run `cargo build` or `cargo update && cargo build` for your project.
315//!
316//! ### Optional Dependencies / Features
317//!
318//! #### Features enabled by default
319//!
320//! * `suggestions`: Turns on the `Did you mean '--myoption'?` feature for when users make typos. (builds dependency `strsim`)
321//! * `color`: Turns on colored error messages. This feature only works on non-Windows OSs. (builds dependency `ansi-term` and `atty`)
322//! * `wrap_help`: Wraps the help at the actual terminal width when
323//!  available, instead of 120 chracters. (builds dependency `textwrap`
324//! with feature `term_size`)
325//!
326//! To disable these, add this to your `Cargo.toml`:
327//!
328//! ```toml
329//! [dependencies.clap]
330//! version = "~2.27.0"
331//! default-features = false
332//! ```
333//!
334//! You can also selectively enable only the features you'd like to include, by adding:
335//!
336//! ```toml
337//! [dependencies.clap]
338//! version = "~2.27.0"
339//! default-features = false
340//!
341//! # Cherry-pick the features you'd like to use
342//! features = [ "suggestions", "color" ]
343//! ```
344//!
345//! #### Opt-in features
346//!
347//! * **"yaml"**: Enables building CLIs from YAML documents. (builds dependency `yaml-rust`)
348//! * **"unstable"**: Enables unstable `clap` features that may change from release to release
349//!
350//! ### Dependencies Tree
351//!
352//! The following graphic depicts `clap`s dependency graph (generated using
353//! [cargo-graph](https://github.com/kbknapp/cargo-graph)).
354//!
355//!  * **Dashed** Line: Optional dependency
356//!  * **Red** Color: **NOT** included by default (must use cargo `features` to enable)
357//!  * **Blue** Color: Dev dependency, only used while developing.
358//!
359//! ![clap dependencies](https://raw.githubusercontent.com/kbknapp/clap-rs/master/clap_dep_graph.png)
360//!
361//! ### More Information
362//!
363//! You can find complete documentation on the [docs.rs](https://docs.rs/clap/) for this project.
364//!
365//! You can also find usage examples in the [examples/] directory of this repo.
366//!
367//! #### Video Tutorials
368//!
369//! There's also the video tutorial series [Argument Parsing with Rust v2][video tutorials].
370//!
371//! These videos slowly trickle out as I finish them and currently a work in progress.
372//!
373//! ## How to Contribute
374//!
375//! Please read [CONTRIBUTING.md](https://raw.githubusercontent.com/clap-rs/clap/master/.github/CONTRIBUTING.md) before you start contributing.
376//!
377//! ### Goals
378//!
379//! There are a few goals of `clap` that I'd like to maintain throughout contributions. If your
380//! proposed changes break, or go against any of these goals we'll discuss the changes further
381//! before merging (but will *not* be ignored, all contributes are welcome!). These are by no means
382//! hard-and-fast rules, as I'm no expert and break them myself from time to time (even if by
383//! mistake or ignorance).
384//!
385//! * Remain backwards compatible when possible
386//!   - If backwards compatibility *must* be broken, use deprecation warnings if at all possible before
387//!   removing legacy code - This does not apply for security concerns
388//! * Parse arguments quickly
389//!   - Parsing of arguments shouldn't slow down usage of the main program - This is also true of
390//!   generating help and usage information (although *slightly* less stringent, as the program is about
391//!   to exit)
392//! * Try to be cognizant of memory usage
393//!   - Once parsing is complete, the memory footprint of `clap` should be low since the  main program
394//!   is the star of the show
395//! * `panic!` on *developer* error, exit gracefully on *end-user* error
396//!
397//! ### Compatibility Policy
398//!
399//! Because `clap` takes `SemVer` and compatibility seriously, this is the official policy regarding
400//! breaking changes and previous versions of Rust.
401//!
402//! `clap` will pin the minimum required version of Rust to the CI builds. Bumping the minimum
403//! version of Rust is considered a minor breaking change, meaning *at a minimum* the minor version
404//! of `clap` will be bumped.
405//!
406//! In order to keep from being suprised of breaking changes, it is **highly** recommended to use
407//! the `~major.minor.patch` style in your `Cargo.toml`:
408//!
409//! ```toml
410//! [dependencies] clap = "~2.27.0"
411//! ```
412//!
413//! This will cause *only* the patch version to be updated upon a `cargo update` call, and therefore
414//! cannot break due to new features, or bumped minimum versions of Rust.
415//!
416//! #### Minimum Version of Rust
417//!
418//! `clap` will officially support current stable Rust, minus two releases, but may work with prior
419//! releases as well. For example, current stable Rust at the time of this writing is 1.21.0,
420//! meaning `clap` is guaranteed to compile with 1.19.0 and beyond. At the 1.22.0 release, `clap`
421//! will be guaranteed to compile with 1.20.0 and beyond, etc.
422//!
423//! Upon bumping the minimum version of Rust (assuming it's within the stable-2 range), it *must* be
424//! clearly annotated in the `CHANGELOG.md`
425//!
426//! ## License
427//!
428//! `clap` is licensed under the MIT license. Please read the [LICENSE-MIT][license] file in
429//! this repository for more information.
430//!
431//! [examples/]: https://github.com/kbknapp/clap-rs/tree/master/examples
432//! [video tutorials]: https://www.youtube.com/playlist?list=PLza5oFLQGTl2Z5T8g1pRkIynR3E0_pc7U
433//! [license]: https://raw.githubusercontent.com/kbknapp/clap-rs/master/LICENSE-MIT
434
435#![crate_type = "lib"]
436#![doc(html_root_url = "https://docs.rs/clap/3.0.0-beta.1")]
437#![deny(
438    missing_docs,
439    missing_debug_implementations,
440    missing_copy_implementations,
441    trivial_casts,
442    unused_import_braces,
443    unused_allocation,
444    trivial_numeric_casts
445)]
446
447#[cfg(not(feature = "std"))]
448compile_error!("`std` feature is currently required to build `clap`");
449
450pub use crate::build::{App, AppSettings, Arg, ArgGroup, ArgSettings};
451pub use crate::derive::{Clap, FromArgMatches, IntoApp, Subcommand};
452pub use crate::parse::errors::{Error, ErrorKind, Result};
453pub use crate::parse::{ArgMatches, OsValues, SubCommand, Values};
454
455#[cfg(feature = "yaml")]
456pub use yaml_rust::YamlLoader;
457
458#[cfg(feature = "derive")]
459#[cfg_attr(feature = "derive", doc(hidden))]
460pub use clap_derive::{self, *};
461
462#[cfg(feature = "derive")]
463#[cfg_attr(feature = "derive", doc(hidden))]
464pub use lazy_static;
465
466#[macro_use]
467#[allow(missing_docs)]
468pub mod macros;
469
470pub mod derive;
471
472mod build;
473mod mkeymap;
474mod output;
475mod parse;
476mod util;
477
478const INTERNAL_ERROR_MSG: &str = "Fatal internal error. Please consider filing a bug \
479                                  report at https://github.com/clap-rs/clap/issues";
480const INVALID_UTF8: &str = "unexpected invalid UTF-8 code point";