bpaf/
lib.rs

1#![warn(missing_docs)]
2#![allow(clippy::needless_doctest_main)]
3#![allow(clippy::redundant_else)] // not useful
4#![allow(rustdoc::redundant_explicit_links)] // two random markdown parsers I tried only supports explicit links
5#![cfg_attr(docsrs, feature(doc_auto_cfg))]
6
7//! Lightweight and flexible command line argument parser with derive and combinatoric style API
8
9//! # Quick links
10//! - [Introduction](_documentation::_0_intro) - features, design goals, restrictions
11//! - [Tutorials](_documentation::_1_tutorials) - practical learning oriented information and
12//!   examples to get you started
13//!   + [Types of arguments](_documentation::_1_tutorials::_0_types_of_arguments) -
14//!     common types of line options and conventions (optional)
15//!   + [Combinatoric API](_documentation::_1_tutorials::_1_combinatoric_api)  -
16//!     Parse arguments without using proc macros
17//!   + [Derive API](_documentation::_1_tutorials::_2_derive_api) -
18//!     Create a parser by defining a structure
19//! - [How-to and guides](_documentation::_2_howto) - assumes familiarity with the basics and
20//!   explains how to concrete tasks
21//! - [Explanations](_documentation::_4_explanation) - theoretical information about abstractions
22//!   used by the library, oriented for understanding
23//! - [FAQ](https://github.com/pacak/bpaf/discussions) - questions from library users
24
25//! # A quick start
26//!
27//! Add `bpaf`, optionally with derive enabled
28//!
29//! ```text
30//! $ cargo add bpaf -F derive,dull_color
31//! ```
32//!
33//! Use either derive or combinatoric API and try running it
34//!
35#![cfg_attr(not(doctest), doc = include_str!("docs2/intro.md"))]
36
37//!
38//! ## Consuming items - making `Parser`
39//!
40//! `bpaf` allows you to describe the parsers using a mix of two APIs: combinatoric and derive.
41//! Both APIs can achieve the same results, you can use one that better suits your needs. You can
42//! find documentation with more examples following those links.
43//!
44//! - For an argument with a name you define [`NamedArg`] using a combination of [`short`],
45//!   [`long`] and [`env`](crate::env()). At the same time you can attach
46//!   [`help`](NamedArg::help).
47//! - [`NamedArg::switch`] - simple switch that returns `true` if it's present on a command
48//!   line and `false` otherwise.
49//! - [`NamedArg::flag`] - a variant of `switch` that lets you return one of two custom
50//!   values, for example `Color::On` and `Color::Off`.
51//! - [`NamedArg::req_flag`] - a variant of `switch` that only only succeeds when it's name
52//!   is present on a command line
53//! - [`NamedArg::argument`] - named argument containing a value, you can further
54//!   customize it with [`adjacent`](crate::parsers::ParseArgument::adjacent)
55//! - [`positional`] - positional argument, you can further customize it with
56//!   [`strict`](ParsePositional::strict)
57//! - [`OptionParser::command`] - subcommand parser.
58//! - [`any`] and its specialized version [`literal`] are escape hatches that can parse anything
59//!   not fitting into usual classification.
60//! - [`pure`] and [`pure_with`] - a way to generate a value that can be composed without parsing
61//!   it from the command line.
62//!
63//! ## Transforming and changing parsers
64//!
65//! By default primitive parsers gives you back a single `bool`, a single `PathBuf` or a single
66//! value produced by [`FromStr`] trait, etc. You can further transform it by chaining methods from
67//! [`Parser`] trait, some of those methods are applied automagically if you are using derive API.
68//!
69//! `bpaf` distinguishes two types of parse failures - "value is absent" and
70//! "value is present but invalid", most parsers listed in this section only handle the first
71//! type of failure by default, but you can use their respective `catch` method to handle the later
72//! one.
73//!
74//! - [`fallback`](Parser::fallback) and [`fallback_with`](Parser::fallback_with) - return a
75//!   different value if parser fails to find what it is looking for. Generated help for former
76//!   can be updated to include default value using
77//!   [`display_fallback`](ParseFallback::display_fallback),
78//!   [`debug_fallback`](ParseFallback::debug_fallback), or
79//!   [`format_fallback`](ParseFallback::format_fallback).
80//! - [`optional`](Parser::optional) - return `None` if value is missing instead of failing, see
81//!   also [`catch`](ParseOptional::catch) .
82//! - [`many`](Parser::many), [`some`](Parser::some) and [`collect`](Parser::collect) - collect
83//!   multiple values into a collection, usually a vector, see their respective
84//!   [`catch`](ParseMany::catch), [`catch`](ParseSome::catch) and [`catch`](ParseCollect::catch).
85//! - [`map`](Parser::map), [`parse`](Parser::parse) and [`guard`](Parser::guard) - transform
86//!   and/or validate value produced by a parser
87//! - [`to_options`](Parser::to_options) - finalize the parser and prepare to run it
88//!
89//! ## Combining multiple parsers together
90//!
91//! Once you have parsers for all the primitive fields figured out you can start combining them
92//! together to produce a parser for a final result - data type you designed in the step one.
93//! For derive API you apply annotations to data types with `#[derive(Bpaf)`] and `#[bpaf(..)]`,
94//! with combinatoric API you use [`construct!`](crate::construct!) macro.
95//!
96//! All fields in a struct needs to be successfully parsed in order for the parser to succeed
97//! and only one variant from enum will consume its values at a time.
98//!
99//! You can use [`adjacent`](ParseCon::adjacent) annotation to parse multiple flags as an adjacent
100//! group allowing for more unusual scenarios such as multiple value arguments or chained commands.
101//!
102//! ## Improving user experience
103//!
104//! `bpaf` would use doc comments on fields and structures in derive mode and and values passed
105//! in various `help` methods to generate `--help` documentation, you can further improve it
106//! using those methods:
107//!
108//! - [`hide_usage`](Parser::hide_usage) and [`hide`](Parser::hide) - hide the parser from
109//!   generated *Usage* line or whole generated help
110//! - [`group_help`](Parser::group_help) and [`with_group_help`](Parser::with_group_help) -
111//!   add a common description shared by several parsers
112//! - [`custom_usage`](Parser::custom_usage) - customize usage for a primitive or composite parser
113//! - [`usage`](OptionParser::usage) and [`with_usage`](OptionParser::with_usage) lets you to
114//!   customize whole usage line as a whole either by completely overriding it or by building around it.
115//!
116//! By default with completion enabled `bpaf` would complete names for flags, arguments and
117//! commands. You can also generate completion for argument values, possible positionals, etc.
118//! This requires enabling **autocomplete** cargo feature.
119//!
120//! - [`complete`](Parser::complete) and [`complete_shell`](Parser::complete_shell)
121//!
122//! And finally you can generate documentation for command line in markdown, html and manpage
123//! formats using [`render_markdown`](OptionParser::render_markdown),
124//! [`render_html`](OptionParser::render_html) and [`render_manpage`](OptionParser::render_manpage),
125//! for more detailed info see [`doc`] module
126//!
127//! ## Testing your parsers and running them
128//! - You can [`OptionParser::run`] the parser on the arguments passed on the command line
129//! - [`check_invariants`](OptionParser::check_invariants) checks for a few invariants in the
130//!   parser `bpaf` relies on
131//! - [`run_inner`](OptionParser::run_inner) runs the parser with custom [`Args`] you can create
132//!   either explicitly or implicitly using one of the [`From`] implementations, `Args` can be
133//!   customized with [`set_comp`](Args::set_comp) and [`set_name`](Args::set_name).
134//! - [`ParseFailure`] contains the parse outcome, you can consume it either by hands or using one
135//!   of [`exit_code`](ParseFailure::exit_code), [`unwrap_stdout`](ParseFailure::unwrap_stdout) and
136//!   [`unwrap_stderr`](ParseFailure::unwrap_stderr)
137//!
138//! ## Cargo features
139//!
140//!  - `derive`: adds a dependency on `bpaf_derive` crate and reexport `Bpaf` derive macro. You
141//!     need to enable it to use derive API. Disabled by default.
142//!
143//!  - `batteries`: helpers implemented with public `bpaf` API. Disabled by default.
144//!
145//!  - `autocomplete`: enables support for shell autocompletion. Disabled by default.
146//!
147//!
148//! - `bright-color`, `dull-color`: use more colors when printing `--help` and such. Enabling
149//!   either color feature adds some extra dependencies and might raise MRSV. If you are planning
150//!   to use this feature in a published app - it’s best to expose them as feature flags:
151//!
152//!    ```toml
153//!    [features]
154//!    bright-color = ["bpaf/bright-color"]
155//!    dull-color = ["bpaf/dull-color"]
156//!    ```
157//!    Disabled by default.
158//!
159//!  - `docgen`: generate documentation from help declaration, see [`OptionParser::render_markdown`] and [`doc`](crate::doc). Disabled by default.
160
161
162
163#[cfg(feature = "extradocs")]
164#[rustfmt::skip]
165#[allow(unused_imports)]
166pub mod _documentation;
167
168mod arg;
169mod args;
170#[cfg(feature = "batteries")]
171pub mod batteries;
172mod buffer;
173#[cfg(feature = "autocomplete")]
174mod complete_gen;
175#[cfg(feature = "autocomplete")]
176mod complete_run;
177#[cfg(feature = "autocomplete")]
178mod complete_shell;
179pub mod doc;
180mod error;
181mod from_os_str;
182mod info;
183mod item;
184mod meta;
185mod meta_help;
186mod meta_youmean;
187pub mod params;
188mod structs;
189#[cfg(test)]
190mod tests;
191
192pub mod parsers {
193    //! This module exposes parsers that accept further configuration with builder pattern
194    //!
195    //! In most cases you won't be using those names directly, they're only listed here to provide
196    //! access to documentation
197    #[cfg(feature = "autocomplete")]
198    #[doc(inline)]
199    pub use crate::complete_shell::ParseCompShell;
200    #[doc(inline)]
201    pub use crate::params::{
202        NamedArg, ParseAny, ParseArgument, ParseCommand, ParseFlag, ParsePositional,
203    };
204    #[doc(inline)]
205    pub use crate::structs::{
206        ParseCollect, ParseCon, ParseCount, ParseFallback, ParseFallbackWith, ParseLast, ParseMany,
207        ParseOptional, ParseSome,
208    };
209}
210
211// -------------------------------------------------------------------
212
213#[doc(inline)]
214pub use crate::{args::Args, buffer::Doc, error::ParseFailure, info::OptionParser};
215
216#[doc(hidden)]
217// used by construct macro, not part of public API
218pub use crate::{args::State, error::Error, meta::Meta, structs::ParseCon};
219
220use std::{marker::PhantomData, str::FromStr};
221
222use crate::{
223    buffer::{MetaInfo, Style},
224    item::Item,
225    params::build_positional,
226    parsers::{NamedArg, ParseAny, ParseCommand, ParsePositional},
227    structs::{
228        ParseCollect, ParseCount, ParseFail, ParseFallback, ParseFallbackWith, ParseGroupHelp,
229        ParseGuard, ParseHide, ParseLast, ParseMany, ParseMap, ParseOptional, ParseOrElse,
230        ParsePure, ParsePureWith, ParseSome, ParseUsage, ParseWith, ParseWithGroupHelp,
231    },
232};
233
234#[cfg(feature = "autocomplete")]
235pub use crate::complete_shell::ShellComp;
236#[cfg(feature = "autocomplete")]
237use structs::ParseComp;
238
239#[doc(inline)]
240#[cfg(feature = "bpaf_derive")]
241pub use bpaf_derive::Bpaf;
242
243/// Compose several parsers to produce a single result
244///
245/// # Usage reference
246/// ```rust
247/// # use bpaf::*;
248/// # { struct Res(bool, bool, bool);
249/// # let a = short('a').switch(); let b = short('b').switch(); let c = short('c').switch();
250/// // structs with unnamed fields:
251/// construct!(Res(a, b, c));
252/// # }
253///
254/// # { struct Res { a: bool, b: bool, c: bool }
255/// # let a = short('a').switch(); let b = short('b').switch(); let c = short('c').switch();
256/// // structs with named fields:
257/// construct!(Res {a, b, c});
258/// # }
259///
260/// # { enum Ty { Res(bool, bool, bool) }
261/// # let a = short('a').switch(); let b = short('b').switch(); let c = short('c').switch();
262/// // enums with unnamed fields:
263/// construct!(Ty::Res(a, b, c));
264/// # }
265///
266/// # { enum Ty { Res { a: bool, b: bool, c: bool } }
267/// # let a = short('a').switch(); let b = short('b').switch(); let c = short('c').switch();
268/// // enums with named fields:
269/// construct!(Ty::Res {a, b, c});
270/// # }
271///
272/// # { let a = short('a').switch(); let b = short('b').switch(); let c = short('c').switch();
273/// // tuples:
274/// construct!(a, b, c);
275/// # }
276///
277/// # { let a = short('a').switch(); let b = short('b').switch(); let c = short('c').switch();
278/// // parallel composition, tries all parsers, picks one that consumes the left most value,
279/// // or if they consume the same (or not at all) - the left most in a list
280/// construct!([a, b, c]);
281/// # }
282///
283/// // defining primitive parsers inside construct macro :)
284/// construct!(a(short('a').switch()), b(long("arg").argument::<usize>("ARG")));
285///
286/// # { let a = short('a').switch();
287/// // defining a boxed parser
288/// construct!(a);
289/// # }
290/// ```
291///
292/// # Combinatoric usage
293/// `construct!` can compose parsers sequentially or in parallel.
294///
295/// Sequential composition runs each parser and if all of them succeed you get a parser object of a
296/// new type back. Placeholder names for values inside `construct!` macro must correspond to both
297/// struct/enum names and parser names present in scope. In examples below `a` corresponds to a
298/// function and `b` corresponds to a variable name. Note parens in `a()`, you must to use them to
299/// indicate function parsers.
300///
301/// Inside the parens you can put a whole expression to use instead of
302/// having to define them in advance: `a(positional::<String>("POS"))`. Probably a good idea to use this
303/// approach only for simple parsers.
304///
305/// ```rust
306/// # use bpaf::*;
307/// struct Res (u32, u32);
308/// enum Ul { T { a: u32, b: u32 } }
309///
310/// // You can share parameters across multiple construct invocations
311/// // if defined as functions
312/// fn a() -> impl Parser<u32> {
313///     short('a').argument::<u32>("N")
314/// }
315///
316/// // You can construct structs or enums with unnamed fields
317/// fn res() -> impl Parser<Res> {
318///     let b = short('b').argument::<u32>("n");
319///     construct!(Res ( a(), b ))
320/// }
321///
322/// // You can construct structs or enums with named fields
323/// fn ult() -> impl Parser<Ul> {
324///     let b = short('b').argument::<u32>("n");
325///     construct!(Ul::T { a(), b })
326/// }
327///
328/// // You can also construct simple tuples
329/// fn tuple() -> impl Parser<(u32, u32)> {
330///     let b = short('b').argument::<u32>("n");
331///     construct!(a(), b)
332/// }
333///
334/// // You can create boxed version of parsers so the type matches as long
335/// // as return type is the same - can be useful for all sort of dynamic parsers
336/// fn boxed() -> Box<dyn Parser<u32>> {
337///     let a = short('a').argument::<u32>("n");
338///     construct!(a)
339/// }
340///
341/// // In addition to having primitives defined before using them - you can also define
342/// // them directly inside construct macro. Probably only a good idea if you have only simple
343/// // components
344/// struct Options {
345///     arg: u32,
346///     switch: bool,
347/// }
348///
349/// fn coyoda() -> impl Parser<Options> {
350///     construct!(Options {
351///         arg(short('a').argument::<u32>("ARG")),
352///         switch(short('s').switch())
353///     })
354/// }
355/// ```
356///
357/// Parallel composition picks one of several available parsers (result types must match) and returns a
358/// parser object of the same type. Similar to sequential composition you can use parsers from variables
359/// or functions:
360///
361/// ```rust
362/// # use bpaf::*;
363/// fn b() -> impl Parser<u32> {
364///     short('b').argument::<u32>("NUM")
365/// }
366///
367/// fn a_or_b() -> impl Parser<u32> {
368///     let a = short('a').argument::<u32>("NUM");
369///     // equivalent way of writing this would be `a.or_else(b())`
370///     construct!([a, b()])
371/// }
372/// ```
373///
374/// # Derive usage
375///
376/// `bpaf` would combine fields of struct or enum constructors sequentially and enum
377/// variants in parallel.
378/// ```rust
379/// # use bpaf::*;
380/// // to satisfy this parser user needs to pass both -a and -b
381/// #[derive(Debug, Clone, Bpaf)]
382/// struct Res {
383///     a: u32,
384///     b: u32,
385/// }
386///
387/// // to satisfy this parser user needs to pass one (and only one) of -a, -b, -c or -d
388/// #[derive(Debug, Clone, Bpaf)]
389/// enum Enumeraton {
390///     A { a: u32 },
391///     B { b: u32 },
392///     C { c: u32 },
393///     D { d: u32 },
394/// }
395///
396/// // here user needs to pass either both -a AND -b or both -c AND -d
397/// #[derive(Debug, Clone, Bpaf)]
398/// enum Ult {
399///     AB { a: u32, b: u32 },
400///     CD { c: u32, d: u32 }
401/// }
402/// ```
403#[macro_export]
404macro_rules! construct {
405    // construct!(Enum::Cons { a, b, c })
406    ($(::)? $ns:ident $(:: $con:ident)* { $($tokens:tt)* }) => {{ $crate::construct!(@prepare [named [$ns $(:: $con)*]] [] $($tokens)*) }};
407
408    // construct!(Enum::Cons ( a, b, c ))
409    ($(::)? $ns:ident $(:: $con:ident)* ( $($tokens:tt)* )) => {{ $crate::construct!(@prepare [pos [$ns $(:: $con)*]] [] $($tokens)*) }};
410
411    // construct!( a, b, c )
412    ($first:ident $($tokens:tt)*) => {{ $crate::construct!(@prepare [pos] [] $first $($tokens)*) }};
413
414    // construct![a, b, c]
415    ([$first:ident $($tokens:tt)*]) => {{ $crate::construct!(@prepare [alt] [] $first $($tokens)*) }};
416
417    (@prepare $ty:tt [$($fields:tt)*] $field:ident () $(, $($rest:tt)*)? ) => {{
418        let $field = $field();
419        $crate::construct!(@prepare $ty [$($fields)* $field] $($($rest)*)?)
420    }};
421    (@prepare $ty:tt [$($fields:tt)*] $field:ident ($expr:expr) $(, $($rest:tt)*)?) => {{
422        let $field = $expr;
423        $crate::construct!(@prepare $ty [$($fields)* $field] $($($rest)*)?)
424    }};
425    (@prepare $ty:tt [$($fields:tt)*] $field:ident $(, $($rest:tt)*)? ) => {{
426        $crate::construct!(@prepare $ty [$($fields)* $field] $($($rest)* )?)
427    }};
428
429    (@prepare [alt] [$first:ident $($fields:ident)*]) => {
430        #[allow(deprecated)]
431        { use $crate::Parser; $first $(.or_else($fields))* }
432    };
433
434    (@prepare $ty:tt [$($fields:tt)*]) => {
435        $crate::construct!(@fin $ty [ $($fields)* ])
436    };
437
438    (@make [named [$($con:tt)+]] [$($fields:ident)*]) => { $($con)+ { $($fields),* } };
439    (@make [pos   [$($con:tt)+]] [$($fields:ident)*]) => { $($con)+ ( $($fields),* ) };
440    (@make [pos] [$($fields:ident)*]) => { ( $($fields),* ) };
441
442
443    (@fin [named [$($con:tt)+]] []) => { $crate::pure($($con)+ { })};
444    (@fin [pos   [$($con:tt)+]] []) => { $crate::pure($($con)+ ( ))};
445
446    (@fin [pos] [$field:ident]) => {{
447        use $crate::Parser;
448        $field.boxed()
449    }};
450
451    (@fin $ty:tt [$front:ident $($fields:ident)*]) => {{
452        use $crate::Parser;
453        let meta = $crate::Meta::And(vec![ $front.meta(), $($fields.meta()),* ]);
454        let inner = move |failfast: bool, args: &mut $crate::State| {
455            let mut $front = $front.eval(args);
456            if failfast {
457                $front = Ok($front?);
458            }
459            $(let $fields = $fields.eval(args);)*
460            let $front = $front?;
461            $(let $fields = $fields?;)*
462
463            args.current = None;
464            ::std::result::Result::Ok::<_, $crate::Error>
465                ($crate::construct!(@make $ty [$front $($fields)*]))
466        };
467        $crate::ParseCon { inner, meta, failfast: false }
468    }};
469}
470
471/// Simple or composed argument parser
472///
473/// # Overview
474///
475/// It's best to think of an object implementing [`Parser`] trait as a container with a value
476/// inside that is composable with other `Parser` containers using [`construct!`] and the only
477/// way to extract this value is by transforming it to [`OptionParser`] with
478/// [`to_options`](Parser::to_options) and running it with [`run`](OptionParser::run). At which
479/// point you either get your value out or `bpaf` would generate a message describing a problem
480/// (missing argument, validation failure, user requested help, etc) and the program would
481/// exit.
482///
483/// Values inside can be of any type for as long as they implement `Debug`, `Clone` and
484/// there are no lifetimes other than static.
485///
486/// When consuming the values you can jump straight to a value that implements
487/// [`FromStr`] trait and then transform it into something that your program would use. Alternatively,
488/// you can consume either `String` or `OsString` and parse that by hand. It's better to perform
489/// as much parsing and validation inside the `Parser` as possible so the program itself gets
490/// strictly typed and correct value while the user gets immediate feedback on what's wrong with the
491/// arguments they pass.
492///
493/// Order of operations matters, each subsequent parser gets the output of the earlier one. Both
494/// parsers `a` and `b` would consume multiple numeric values, each less than 10, but `a`
495/// validates a single value and then consumes multiple of them already validated, while `b` first
496/// consumes and then performs validation. The former approach is usually more readable.
497/// ```rust
498/// # use bpaf::*;
499/// # fn simple() {
500/// let a = short('a').argument::<usize>("N")
501///     .guard(|&a| a < 10, "`a` must be below 10")
502///     .many();
503/// let b = short('b').argument::<usize>("N")
504///     .many()
505///     .guard(|bs| bs.iter().all(|&b| b < 10), "`b` must be below 10");
506/// # }
507/// ```
508///
509/// The same logic applies to derive API - the current type depends on the order of annotations:
510/// ```rust
511/// # use bpaf::*;
512/// # fn less_than_10(a: &usize) -> bool { true }
513/// # fn all_less_than_10(a: &Vec<usize>) -> bool { true }
514/// #[derive(Bpaf, Debug, Clone)]
515/// struct Simple {
516///     #[bpaf(argument("N"), guard(less_than_10, "`a` must be below 10"), many)]
517///     a: Vec<usize>,
518///     #[bpaf(argument("N"), many, guard(all_less_than_10, "`b` must be below 10"))]
519///     b: Vec<usize>,
520/// }
521/// ```
522///
523/// For example suppose your program needs the user to specify dimensions of a rectangle, with sides
524/// being 1..20 units long and the total area must not exceed 200 units square. A parser that
525/// consumes it might look like this:
526///
527/// ```rust
528/// # use bpaf::*;
529/// #[derive(Debug, Copy, Clone)]
530/// struct Rectangle {
531///     width: u32,
532///     height: u32,
533/// }
534///
535/// fn rectangle() -> impl Parser<Rectangle> {
536///     let invalid_size = "Sides of a rectangle must be 1..20 units long";
537///     let invalid_area = "Area of a rectangle must not exceed 200 units square";
538///     let width = long("width")
539///         .help("Width of the rectangle")
540///         .argument::<u32>("PX")
541///         .guard(|&x| 1 <= x && x <= 10, invalid_size);
542///     let height = long("height")
543///         .help("Height of the rectangle")
544///         .argument::<u32>("PX")
545///         .guard(|&x| 1 <= x && x <= 10, invalid_size);
546///     construct!(Rectangle { width, height })
547///         .guard(|&r| r.width * r.height <= 400, invalid_area)
548/// }
549/// ```
550///
551///
552/// # Derive specific considerations
553///
554/// Every method defined on this trait belongs to the `postprocessing` section of the field
555/// annotation. `bpaf` would try to figure out what chain to use for as long as there are no
556/// options changing the type: you can use [`fallback`](Parser::fallback_with),
557/// [`fallback_with`](Parser::fallback_with), [`guard`](Parser::guard), [`hide`](Parser::hide`) and
558/// [`group_help`](Parser::group_help) but not the rest of them.
559///
560/// ```rust
561/// # use bpaf::*;
562/// #[derive(Debug, Clone, Bpaf)]
563/// struct Options {
564///     // no annotation at all - `bpaf` inserts implicit `argument` and gets the right type
565///     number_1: u32,
566///
567///     // fallback isn't changing the type so `bpaf` still handles it
568///     #[bpaf(fallback(42))]
569///     number_2: u32,
570///
571///     // `bpaf` inserts implicit `argument`, `optional` and the right type
572///     number_3: Option<u32>,
573///
574///     // fails to compile: you need to specify `argument`
575///     // #[bpaf(optional)]
576///     // number_4: Option<u32>,
577///
578///     #[bpaf(argument("N"), optional)]
579///     number_5: Option<u32>,
580///
581///     // explicit consumer and a full postprocessing chain
582///     #[bpaf(argument::<u32>("N"), optional)]
583///     number_6: Option<u32>,
584/// }
585/// ```
586pub trait Parser<T> {
587    /// Evaluate inner function
588    ///
589    /// Mostly internal implementation details, you can try using it to test your parsers
590    // it's possible to move this function from the trait to the structs but having it
591    // in the trait ensures the composition always works
592    #[doc(hidden)]
593    fn eval(&self, args: &mut State) -> Result<T, Error>;
594
595    /// Included information about the parser
596    ///
597    /// Mostly internal implementation details, you can try using it to test your parsers
598    // it's possible to move this function from the trait to the structs but having it
599    // in the trait ensures the composition always works
600    #[doc(hidden)]
601    fn meta(&self) -> Meta;
602
603    // change shape
604    // {{{ many
605    /// Consume zero or more items from a command line and collect them into a [`Vec`]
606    ///
607    /// `many` preserves any parsing failures and propagates them outwards, with an extra
608    /// [`catch`](ParseMany::catch) statement you can instead stop at the first value
609    /// that failed to parse and ignore it and all the subsequent ones.
610    ///
611    /// `many` will collect at most one result that does not consume anything from the argument
612    /// list allowing using it in combination with any parsers with a fallback. After the first
613    /// one, it will keep collecting the results as long as they consume something.
614    ///
615    /// For derive usage `bpaf` would insert implicit `many` when the resulting type is a
616    /// vector.
617    ///
618    #[cfg_attr(not(doctest), doc = include_str!("docs2/many.md"))]
619    ///
620    /// # See also
621    /// [`some`](Parser::some) also collects results to a vector but requires at least one
622    /// element to succeed, [`collect`](Parser::collect) collects results into a [`FromIterator`]
623    /// structure
624    fn many(self) -> ParseMany<Self>
625    where
626        Self: Sized,
627    {
628        ParseMany {
629            inner: self,
630            catch: false,
631        }
632    }
633    // }}}
634
635    // {{{ collect
636    /// Transform parser into a collection parser
637    ///
638    /// A generic variant of [`many`](Parser::many), instead of collecting into a vector
639    /// it collects into any collection that implements [`FromIterator`] trait
640    ///
641    /// `collect` preserves any parsing failures and propagates them outwards, with extra
642    /// [`catch`](ParseCollect::catch) statement you can instead stop at the first value
643    /// that failed to parse and ignore it and all the subsequent ones.
644    ///
645    #[cfg_attr(not(doctest), doc = include_str!("docs2/collect.md"))]
646    ///
647    /// `collect` will collect at most one result that does not consume anything from the argument
648    /// list allowing using it in combination of any parsers with a fallback. After the first one
649    /// it will keep collecting the results as long as they consume something.
650    fn collect<C>(self) -> ParseCollect<Self, C, T>
651    where
652        C: FromIterator<T>,
653        Self: Sized,
654    {
655        ParseCollect {
656            inner: self,
657            catch: false,
658            ctx: PhantomData,
659        }
660    }
661    // }}}
662
663    // {{{ some
664    /// Consume one or more items from a command line and collect them into a [`Vec`]
665    ///
666    /// Takes a string used as an error message if there are no specified parameters
667    ///
668    /// `some` preserves any parsing failures and propagates them outwards, with an extra
669    /// [`catch`](ParseSome::catch) statement you can instead stop at the first value
670    /// that failed to parse and ignore it and all the subsequent ones.
671    ///
672    /// `some` will collect at most one result that does not consume anything from the argument
673    /// list allowing using it in combination with any parsers with a fallback. After the first
674    /// one, it will keep collecting the results as long as they consume something.
675    ///
676    #[cfg_attr(not(doctest), doc = include_str!("docs2/some.md"))]
677    ///
678    /// # See also
679    /// [`many`](Parser::many) also collects results to a vector but succeeds with
680    /// no matching values. [`collect`](Parser::collect) collects results into a [`FromIterator`]
681    /// structure
682    #[must_use]
683    fn some(self, message: &'static str) -> ParseSome<Self>
684    where
685        Self: Sized + Parser<T>,
686    {
687        ParseSome {
688            inner: self,
689            message,
690            catch: false,
691        }
692    }
693    // }}}
694
695    // {{{ optional
696    /// Turn a required argument into an optional one
697    ///
698    /// `optional` converts any missing items into `None` and passes the remaining parsing
699    /// failures untouched. With an extra [`catch`](ParseOptional::catch) statement, you can handle
700    /// those failures too.
701    ///
702    /// # Derive usage
703    ///
704    /// By default, `bpaf` would automatically use optional for fields of type `Option<T>`,
705    /// for as long as it's not prevented from doing so by present postprocessing options.
706    /// But it's also possible to specify it explicitly.
707    ///
708    #[cfg_attr(not(doctest), doc = include_str!("docs2/optional.md"))]
709    ///
710    #[must_use]
711    fn optional(self) -> ParseOptional<Self>
712    where
713        Self: Sized + Parser<T>,
714    {
715        ParseOptional {
716            inner: self,
717            catch: false,
718        }
719    }
720    // }}}
721
722    #[must_use]
723    /// Count how many times the inner parser succeeds, and return that number.
724    ///
725    /// When you are dealing with a parser that can succeed without consuming
726    /// anything from a command line - `bpaf` will count first such success as well.
727    ///
728    #[cfg_attr(not(doctest), doc = include_str!("docs2/count.md"))]
729    fn count(self) -> ParseCount<Self, T>
730    where
731        Self: Sized + Parser<T>,
732    {
733        ParseCount {
734            inner: self,
735            ctx: PhantomData,
736        }
737    }
738
739    #[must_use]
740    /// Apply the inner parser as many times as it succeeds, return the last value
741    ///
742    /// You can use this to allow users to pick contradicting options
743    #[cfg_attr(not(doctest), doc = include_str!("docs2/last.md"))]
744    fn last(self) -> ParseLast<Self>
745    where
746        Self: Sized + Parser<T>,
747    {
748        ParseLast { inner: self }
749    }
750
751    // parse
752    // {{{ parse
753    /// Apply a failing transformation to a contained value
754    ///
755    /// Transformation preserves the present/absent state of the value: to parse an optional value you
756    /// can either first try to `parse` it and then mark it as [`optional`](Parser::optional) or first
757    /// deal with the optionality and then parse a value wrapped in [`Option`]. In most cases
758    /// the former approach is more concise.
759    ///
760    /// Similarly, it is possible to parse multiple items with [`many`](Parser::many) or
761    /// [`some`](Parser::some) by either parsing a single item first and then turning it into a [`Vec`]
762    /// or collecting them into a [`Vec`] first and then parsing the whole vector. The former approach
763    /// is more concise.
764    ///
765    /// This is a most general of transforming parsers and you can express
766    /// [`map`](Parser::map) and [`guard`](Parser::guard) in terms of it.
767    ///
768    /// Examples are a bit artificial, to parse a value from a string you can specify
769    /// the type directly in the `argument`'s turbofish and then apply `map`.
770    ///
771    /// # Derive usage:
772    /// `parse` takes a single parameter: function name to call. Function type should match
773    /// parameter `F` used by `parse` in combinatoric API.
774    ///
775    #[cfg_attr(not(doctest), doc = include_str!("docs2/parse.md"))]
776    ///
777    fn parse<F, R, E>(self, f: F) -> ParseWith<T, Self, F, E, R>
778    where
779        Self: Sized + Parser<T>,
780        F: Fn(T) -> Result<R, E>,
781        E: ToString,
782    {
783        ParseWith {
784            inner: self,
785            inner_res: PhantomData,
786            parse_fn: f,
787            res: PhantomData,
788            err: PhantomData,
789        }
790    }
791    // }}}
792
793    // {{{ map
794    /// Apply a pure transformation to a contained value
795    ///
796    /// A common case of the [`parse`](Parser::parse) method, exists mostly for convenience.
797    ///
798    /// # Derive usage:
799    /// The `map` takes a single parameter: function name to call. This function should transform
800    /// the value produced by the parser into a new value of the same or different type.
801    ///
802    #[cfg_attr(not(doctest), doc = include_str!("docs2/map.md"))]
803    ///
804    fn map<F, R>(self, map: F) -> ParseMap<T, Self, F, R>
805    where
806        Self: Sized + Parser<T>,
807        F: Fn(T) -> R + 'static,
808    {
809        ParseMap {
810            inner: self,
811            inner_res: PhantomData,
812            map_fn: map,
813            res: PhantomData,
814        }
815    }
816    // }}}
817
818    // {{{ guard
819    /// Validate or fail with a message
820    ///
821    /// If the value doesn't satisfy the constraint - the parser fails with the specified error message.
822    ///
823    /// # Derive usage
824    /// Derive variant of the `guard` takes a function name instead of a closure, mostly to keep things
825    /// clean. The second argument can be either a string literal or a constant name for a static [`str`].
826    ///
827    #[cfg_attr(not(doctest), doc = include_str!("docs2/guard.md"))]
828    ///
829    #[must_use]
830    fn guard<F>(self, check: F, message: &'static str) -> ParseGuard<Self, F>
831    where
832        Self: Sized + Parser<T>,
833        F: Fn(&T) -> bool,
834    {
835        ParseGuard {
836            inner: self,
837            check,
838            message,
839        }
840    }
841    // }}}
842
843    // combine
844    // {{{ fallback
845    /// Use this value as default if the value isn't present on a command line
846    ///
847    /// Parser would still fail if the value is present but failure comes from some transformation
848    ///
849    #[cfg_attr(not(doctest), doc = include_str!("docs2/dis_fallback.md"))]
850    ///
851    /// # See also
852    /// [`fallback_with`](Parser::fallback_with) would allow to try to fallback to a value that
853    /// comes from a failing computation such as reading a file. By default, the fallback value will
854    /// not be shown in the `--help` output; you can change that by using
855    /// [`display_fallback`](ParseFallback::display_fallback),
856    /// [`debug_fallback`](ParseFallback::debug_fallback), or
857    /// [`format_fallback`](ParseFallback::format_fallback).
858    #[must_use]
859    fn fallback(self, value: T) -> ParseFallback<Self, T>
860    where
861        Self: Sized + Parser<T>,
862    {
863        ParseFallback {
864            inner: self,
865            value,
866            value_str: String::new(),
867        }
868    }
869    // }}}
870
871    // {{{ fallback_with
872    /// Use value produced by this function as default if the value isn't present
873    ///
874    /// Would still fail if the value is present but failure comes from some earlier transformation
875    ///
876    #[cfg_attr(not(doctest), doc = include_str!("docs2/dis_fallback_with.md"))]
877    ///
878    /// # See also
879    /// [`fallback`](Parser::fallback) implements similar logic expect that failures aren't expected.
880    /// By default, the fallback value will
881    /// not be shown in the `--help` output; you can change that by using
882    /// [`display_fallback`](ParseFallbackWith::display_fallback),
883    /// [`debug_fallback`](ParseFallbackWith::debug_fallback), or
884    /// [`format_fallback`](ParseFallbackWith::format_fallback).
885    #[must_use]
886    fn fallback_with<F, E>(self, fallback: F) -> ParseFallbackWith<T, Self, F, E>
887    where
888        Self: Sized + Parser<T>,
889        F: Fn() -> Result<T, E>,
890        E: ToString,
891    {
892        ParseFallbackWith {
893            inner: self,
894            inner_res: PhantomData,
895            fallback,
896            value_str: String::new(),
897            err: PhantomData,
898        }
899    }
900    // }}}
901
902    // {{{ or_else
903    /// If first parser fails - try the second one
904    ///
905    /// For parser to succeed eiter of the components needs to succeed. If both succeed - `bpaf`
906    /// would use output from one that consumed the left most value. The second flag on the command
907    /// line remains unconsumed by `or_else`.
908    ///
909    /// # Combinatoric usage:
910    /// There's two ways to write this combinator with identical results:
911    /// ```rust
912    /// # use bpaf::*;
913    /// fn a() -> impl Parser<u32> {
914    ///     short('a').argument::<u32>("NUM")
915    /// }
916    ///
917    /// fn b() -> impl Parser<u32> {
918    ///     short('b').argument::<u32>("NUM")
919    /// }
920    ///
921    /// fn a_or_b_comb() -> impl Parser<u32> {
922    ///     construct!([a(), b()])
923    /// }
924    ///
925    /// fn a_or_b_comb2() -> impl Parser<u32> {
926    ///     a().or_else(b())
927    /// }
928    /// ```
929    ///
930    /// # Example
931    /// ```console
932    /// $ app -a 12 -b 3
933    /// // 12
934    /// $ app -b 3 -a 12
935    /// // 3
936    /// $ app -b 13
937    /// // 13
938    /// $ app
939    /// // fails asking for either -a NUM or -b NUM
940    /// ```
941    ///
942    /// # Derive usage:
943    ///
944    /// `bpaf` translates enum into alternative combinations, different shapes of variants
945    /// produce different results.
946    ///
947    ///
948    /// ```bpaf
949    /// # use bpaf::*;
950    /// #[derive(Debug, Clone, Bpaf)]
951    /// enum Flag {
952    ///     A { a: u32 }
953    ///     B { b: u32 }
954    /// }
955    /// ```
956    ///
957    /// ```console
958    /// $ app -a 12 -b 3
959    /// // Flag::A { a: 12 }
960    /// $ app -b 3 -a 12
961    /// // Flag::B { b: 3 }
962    /// $ app -b 3
963    /// // Flag::B { b: 3 }
964    /// $ app
965    /// // fails asking for either -a NUM or -b NUM
966    /// ```
967    ///
968    /// # Performance
969    ///
970    /// `bpaf` tries to evaluate both branches regardless of the successes to produce a
971    /// better error message for combinations of mutually exclusive parsers:
972    /// Suppose program accepts one of two mutually exclusive switches `-a` and `-b`
973    /// and both are present error message should point at the second flag
974    #[doc(hidden)]
975    #[deprecated(
976        since = "0.5.0",
977        note = "instead of a.or_else(b) you should use construct!([a, b])"
978    )]
979    fn or_else<P>(self, alt: P) -> ParseOrElse<T>
980    where
981        Self: Sized + Parser<T> + 'static,
982        P: Sized + Parser<T> + 'static,
983    {
984        ParseOrElse {
985            this: Box::new(self),
986            that: Box::new(alt),
987        }
988    }
989    // }}}
990
991    // misc
992    // {{{ hide
993    /// Ignore this parser during any sort of help generation
994    ///
995    /// Best used for optional parsers or parsers with a defined fallback, usually for implementing
996    /// backward compatibility or hidden aliases
997    ///
998    #[cfg_attr(not(doctest), doc = include_str!("docs2/hide.md"))]
999    ///
1000    fn hide(self) -> ParseHide<Self>
1001    where
1002        Self: Sized + Parser<T>,
1003    {
1004        ParseHide { inner: self }
1005    }
1006    // }}}
1007
1008    /// Ignore this parser when generating a usage line
1009    ///
1010    /// Parsers hidden from usage will still show up in the available arguments list. Best used on
1011    /// optional things that augment the main application functionality but not define it.
1012    /// Alternatively, you can use [`custom_usage`](Parser::custom_usage) to replace a single
1013    /// option or a group of them with some other text.
1014    #[cfg_attr(not(doctest), doc = include_str!("docs2/hide_usage.md"))]
1015    #[must_use]
1016    fn hide_usage(self) -> ParseUsage<Self>
1017    where
1018        Self: Sized + Parser<T>,
1019    {
1020        ParseUsage {
1021            inner: self,
1022            usage: Doc::default(),
1023        }
1024    }
1025
1026    /// Customize how this parser looks like in the usage line
1027    ///
1028    #[cfg_attr(not(doctest), doc = include_str!("docs2/custom_usage.md"))]
1029    #[must_use]
1030    fn custom_usage<M>(self, usage: M) -> ParseUsage<Self>
1031    where
1032        M: Into<Doc>,
1033        Self: Sized + Parser<T>,
1034    {
1035        ParseUsage {
1036            inner: self,
1037            usage: usage.into(),
1038        }
1039    }
1040
1041    // {{{ group_help
1042    /// Attach a help message to a complex parser
1043    ///
1044    /// `bpaf` inserts the group help message before the block with all the fields
1045    /// from the inner parser and an empty line after the block.
1046    ///
1047    #[cfg_attr(not(doctest), doc = include_str!("docs2/group_help.md"))]
1048    fn group_help<M: Into<Doc>>(self, message: M) -> ParseGroupHelp<Self>
1049    where
1050        Self: Sized + Parser<T>,
1051    {
1052        ParseGroupHelp {
1053            inner: self,
1054            message: message.into(),
1055        }
1056    }
1057    // }}}
1058
1059    /// Make a help message for a complex parser from its [`MetaInfo`]
1060    ///
1061    #[cfg_attr(not(doctest), doc = include_str!("docs2/with_group_help.md"))]
1062    fn with_group_help<F>(self, f: F) -> ParseWithGroupHelp<Self, F>
1063    where
1064        Self: Sized + Parser<T>,
1065        F: Fn(MetaInfo) -> Doc,
1066    {
1067        ParseWithGroupHelp { inner: self, f }
1068    }
1069
1070    // {{{ comp
1071    /// Dynamic shell completion
1072    ///
1073    /// Allows to generate autocompletion information for the shell. Completer places generated input
1074    /// in place of metavar placeholders, so running `completer` on something that doesn't have a
1075    /// [`positional`] or an [`argument`](NamedArg::argument) doesn't make much sense.
1076    ///
1077    /// Takes a function as a parameter that tries to complete partial input to a full one with an
1078    /// optional description. `bpaf` would substitute a current positional item or an argument with an empty
1079    /// string if a value isn't available yet so it's best to run `complete` where parsing can't fail:
1080    /// right after [`argument`](NamedArg::argument) or [`positional`], but this isn't enforced.
1081    ///
1082    /// # Example
1083    /// ```console
1084    /// $ app --name L<TAB>
1085    /// $ app --name Lupusregina _
1086    /// ```
1087    ///
1088    #[cfg_attr(not(doctest), doc = include_str!("docs2/complete.md"))]
1089    ///
1090    /// ## A simple example
1091    ///
1092    #[cfg_attr(not(doctest), doc = include_str!("docs2/simple_dynamic.md"))]
1093    ///
1094    /// ## More detailed example
1095    ///
1096    #[cfg_attr(not(doctest), doc = include_str!("docs2/derive_show_asm.md"))]
1097    ///
1098    #[cfg(feature = "autocomplete")]
1099    fn complete<M, F>(self, op: F) -> ParseComp<Self, F>
1100    where
1101        M: Into<String>,
1102        F: Fn(&T) -> Vec<(M, Option<M>)>,
1103        Self: Sized + Parser<T>,
1104    {
1105        ParseComp {
1106            inner: self,
1107            op,
1108            group: None,
1109        }
1110    }
1111    // }}}
1112
1113    // {{{
1114    /// Static shell completion
1115    ///
1116    /// Allows to ask existing shell completion to provide some information such as a file or
1117    /// directory names or pass through existing shell completion scripts, see
1118    /// [`ShellComp`](complete_shell::ShellComp) for accessible functionality
1119    ///
1120    /// Places function calls in place of metavar placeholder, so running `complete_shell` on
1121    /// something that doesn't have a [`positional`] or [`argument`](NamedArg::argument) doesn't
1122    /// make much sense.
1123    ///
1124    /// # Example
1125    /// ```console
1126    /// $ app --output C<TAB>
1127    /// $ app --output Cargo.toml _
1128    /// ```
1129    ///
1130    /// # Combinatoric usage
1131    /// ```rust
1132    /// # use bpaf::*;
1133    /// fn output() -> impl Parser<String> {
1134    ///     long("output")
1135    ///         .help("Cargo.toml file to use as output")
1136    ///         .argument("OUTPUT")
1137    ///         .complete_shell(ShellComp::File { mask: Some("*.toml") })
1138    /// }
1139    /// ```
1140    ///
1141    /// # Derive usage
1142    /// ```rust
1143    /// # use bpaf::*;
1144    /// #[derive(Debug, Clone, Bpaf)]
1145    /// struct Options {
1146    ///     /// Cargo.toml file to use as output
1147    ///     #[bpaf(argument("OUTPUT"), complete_shell(ShellComp::File { mask: Some("*.toml") }))]
1148    ///     output: String,
1149    /// }
1150    /// ```
1151    ///
1152    /// For multiple file types correct mask syntax is `"*.(toml|md)"`.
1153    #[cfg(feature = "autocomplete")]
1154    fn complete_shell(
1155        self,
1156        op: complete_shell::ShellComp,
1157    ) -> crate::complete_shell::ParseCompShell<Self>
1158    where
1159        Self: Sized + Parser<T>,
1160    {
1161        crate::complete_shell::ParseCompShell { inner: self, op }
1162    }
1163    // }}}
1164
1165    // consume
1166    // {{{ to_options
1167    /// Transform `Parser` into [`OptionParser`] to get ready to [`run`](OptionParser::run) it
1168    ///
1169    ///
1170    /// # Derive usage
1171    /// Add a top-level `options` annotation to generate [`OptionParser`] instead of default
1172    /// [`Parser`].
1173    ///
1174    /// In addition to `options` annotation, you can also specify either `version` or
1175    /// `version(value)` annotation. The former uses version from `cargo`, later uses the
1176    /// specified value which should be an expression of type `&'static str`, see
1177    /// [`version`](OptionParser::version).
1178    ///
1179    #[cfg_attr(not(doctest), doc = include_str!("docs2/to_options.md"))]
1180    ///
1181    /// # See also
1182    /// There's some methods implemented on [`OptionParser`] directly to customize the appearance
1183    fn to_options(self) -> OptionParser<T>
1184    where
1185        Self: Sized + Parser<T> + 'static,
1186    {
1187        OptionParser {
1188            info: info::Info::default(),
1189            inner: Box::new(self),
1190        }
1191    }
1192    // }}}
1193
1194    /// Finalize and run the parser
1195    ///
1196    /// Generally, you'd want to use [`Parser::to_options`] to finalize the parser and [`OptionParser::run`],
1197    /// but this also works for simple cases:
1198    ///
1199    /// ```no_run
1200    /// # use bpaf::*;
1201    /// fn main() {
1202    ///     let name = short('n').long("name").argument::<String>("USER").run();
1203    ///     // do things with name
1204    /// }
1205    /// ```
1206    fn run(self) -> T
1207    where
1208        Self: Sized + Parser<T> + 'static,
1209    {
1210        self.to_options().run()
1211    }
1212
1213    /// Create a boxed representation for a parser
1214    ///
1215    /// The boxed parser doesn't expose internal representation in its type and allows to return
1216    /// of different parsers in different conditional branches
1217    ///
1218    /// You can create it with a single argument `construct` macro or by using `boxed` annotation
1219    #[cfg_attr(not(doctest), doc = include_str!("docs2/boxed.md"))]
1220    fn boxed(self) -> Box<dyn Parser<T>>
1221    where
1222        Self: Sized + Parser<T> + 'static,
1223    {
1224        Box::new(self)
1225    }
1226}
1227
1228/// Parser that produces a fixed value
1229///
1230/// This parser produces `T` without consuming anything from the command line, which can be useful
1231/// with [`construct!`]. As with any parsers, `T` should be `Clone` and `Debug`.
1232///
1233/// Both `pure` and [`pure_with`] are designed to put values into structures, to generate fallback
1234/// you should be using [`fallback`](Parser::fallback) and [`fallback_with`](Parser::fallback_with).
1235///
1236/// See also [`pure_with`] for a pure computation that can fail.
1237///
1238#[cfg_attr(not(doctest), doc = include_str!("docs2/pure.md"))]
1239#[must_use]
1240pub fn pure<T>(val: T) -> ParsePure<T> {
1241    ParsePure(val)
1242}
1243
1244/// Wrap a calculated value into a `Parser`
1245///
1246/// This parser represents a possibly failing equivalent to [`pure`].
1247/// It produces `T` by invoking the provided callback without consuming anything from the command
1248/// line, which can be useful with [`construct!`]. As with any parsers, `T` should be `Clone`
1249/// and `Debug`.
1250///
1251/// Both [`pure`] and `pure_with` are designed to put values into structures, to generate fallback
1252/// you should be using [`fallback`](Parser::fallback) and [`fallback_with`](Parser::fallback_with).
1253///
1254/// See also [`pure`] for a pure computation that can't fail.
1255///
1256#[cfg_attr(not(doctest), doc = include_str!("docs2/pure_with.md"))]
1257pub fn pure_with<T, F, E>(val: F) -> ParsePureWith<T, F, E>
1258where
1259    F: Fn() -> Result<T, E>,
1260    E: ToString,
1261{
1262    ParsePureWith(val)
1263}
1264
1265/// Fail with a fixed error message
1266///
1267/// This parser produces `T` of any type but instead of producing it when asked - it fails
1268/// with a custom error message. Can be useful for creating custom logic
1269///
1270/// # Combinatoric usage
1271/// ```rust
1272/// # use bpaf::*;
1273/// fn must_agree() -> impl Parser<()> {
1274///     let a = long("accept").req_flag(());
1275///     let no_a = fail("You must accept the license agreement with --agree before proceeding");
1276///     construct!([a, no_a])
1277/// }
1278/// ```
1279///
1280/// # Example
1281/// ```console
1282/// $ app
1283/// // exits with "You must accept the license agreement with --agree before proceeding"
1284/// $ app --agree
1285/// // succeeds
1286/// ```
1287#[must_use]
1288pub fn fail<T>(msg: &'static str) -> ParseFail<T> {
1289    ParseFail {
1290        field1: msg,
1291        field2: PhantomData,
1292    }
1293}
1294
1295/// Parse a [`flag`](NamedArg::flag)/[`switch`](NamedArg::switch)/[`argument`](NamedArg::argument) that has a short name
1296///
1297/// You can chain multiple [`short`](NamedArg::short), [`long`](NamedArg::long) and
1298/// [`env`](NamedArg::env()) for multiple names. You can specify multiple names of the same type,
1299///  `bpaf` would use items past the first one as hidden aliases.
1300#[cfg_attr(not(doctest), doc = include_str!("docs2/short_long_env.md"))]
1301#[must_use]
1302pub fn short(short: char) -> NamedArg {
1303    NamedArg {
1304        short: vec![short],
1305        env: Vec::new(),
1306        long: Vec::new(),
1307        help: None,
1308    }
1309}
1310
1311/// Parse a [`flag`](NamedArg::flag)/[`switch`](NamedArg::switch)/[`argument`](NamedArg::argument) that has a long name
1312///
1313/// You can chain multiple [`short`](NamedArg::short), [`long`](NamedArg::long) and
1314/// [`env`](NamedArg::env()) for multiple names. You can specify multiple names of the same type,
1315///  `bpaf` would use items past the first one as hidden aliases.
1316///
1317#[cfg_attr(not(doctest), doc = include_str!("docs2/short_long_env.md"))]
1318#[must_use]
1319pub fn long(long: &'static str) -> NamedArg {
1320    NamedArg {
1321        short: Vec::new(),
1322        long: vec![long],
1323        env: Vec::new(),
1324        help: None,
1325    }
1326}
1327
1328/// Parse an environment variable
1329///
1330/// You can chain multiple [`short`](NamedArg::short), [`long`](NamedArg::long) and
1331/// [`env`](NamedArg::env()) for multiple names. You can specify multiple names of the same type,
1332///  `bpaf` would use items past the first one as hidden aliases.
1333///
1334/// For [`flag`](NamedArg::flag) and [`switch`](NamedArg::switch) environment variable being present
1335/// gives the same result as the flag being present, allowing to implement things like `NO_COLOR`
1336/// variables:
1337///
1338/// ```console
1339/// $ NO_COLOR=1 app --do-something
1340/// ```
1341///
1342/// If you don't specify a short or a long name - whole argument is going to be absent from the
1343/// help message. Use it combined with a named or positional argument to have a hidden fallback
1344/// that wouldn't leak sensitive info.
1345///
1346#[cfg_attr(not(doctest), doc = include_str!("docs2/short_long_env.md"))]
1347#[must_use]
1348pub fn env(variable: &'static str) -> NamedArg {
1349    NamedArg {
1350        short: Vec::new(),
1351        long: Vec::new(),
1352        help: None,
1353        env: vec![variable],
1354    }
1355}
1356
1357/// Parse a positional argument
1358///
1359/// For named flags and arguments ordering generally doesn't matter: most programs would
1360/// understand `-O2 -v` the same way as `-v -O2`, but for positional items order matters: in *nix
1361/// `cat hello world` and `cat world hello` would display contents of the same two files but in
1362/// a different order.
1363///
1364/// When using combinatoric API you can specify the type with turbofish, for parsing types
1365/// that don't implement [`FromStr`] you can use consume a `String`/`OsString` first and parse
1366/// it by hand.
1367/// ```no_run
1368/// # use bpaf::*;
1369/// fn parse_pos() -> impl Parser<usize> {
1370///     positional::<usize>("POS")
1371/// }
1372/// ```
1373///
1374/// # Important restriction
1375/// To parse positional arguments from a command line you should place parsers for all your
1376/// named values before parsers for positional items and commands. In derive API fields parsed as
1377/// positional items or commands should be at the end of your `struct`/`enum`. The same rule applies
1378/// to parsers with positional fields or commands inside: such parsers should go to the end as well.
1379///
1380/// Use [`check_invariants`](OptionParser::check_invariants) in your test to ensure correctness.
1381///
1382/// For example for non-positional `non_pos` and positional `pos` parsers
1383/// ```rust
1384/// # use bpaf::*;
1385/// # let non_pos = || short('n').switch();
1386/// # let pos = ||positional::<String>("POS");
1387/// let valid = construct!(non_pos(), pos());
1388/// let invalid = construct!(pos(), non_pos());
1389/// ```
1390///
1391/// **`bpaf` panics during help generation unless this restriction holds**
1392///
1393/// Without using `--` `bpaf` would only accept items that don't start with `-` as positional, you
1394/// can use [`any`] to work around this restriction.
1395///
1396/// By default `bpaf` accepts positional items with or without `--` where values permit, you can
1397/// further restrict the parser to accept positional items only on the right side of `--` using
1398/// [`strict`](ParsePositional::strict).
1399#[cfg_attr(not(doctest), doc = include_str!("docs2/positional.md"))]
1400#[must_use]
1401pub fn positional<T>(metavar: &'static str) -> ParsePositional<T> {
1402    build_positional(metavar)
1403}
1404
1405#[doc(hidden)]
1406#[deprecated = "You should switch from command(name, sub) to sub.command(name)"]
1407pub fn command<T>(name: &'static str, subparser: OptionParser<T>) -> ParseCommand<T>
1408where
1409    T: 'static,
1410{
1411    ParseCommand {
1412        longs: vec![name],
1413        shorts: Vec::new(),
1414        help: subparser.short_descr(),
1415        subparser,
1416        adjacent: false,
1417    }
1418}
1419
1420/// Parse a single arbitrary item from a command line
1421///
1422/// **`any` is designed to consume items that don't fit into the usual [`flag`](NamedArg::flag)
1423/// /[`switch`](NamedArg::switch)/[`argument`](NamedArg::argument)/[`positional`]/
1424/// [`command`](OptionParser::command) classification, in most cases you don't need to use it**
1425///
1426/// By default, `any` behaves similarly to [`positional`] so you should be using it near the
1427/// rightmost end of the consumer struct and it will only try to parse the first unconsumed item
1428/// on the command line. It is possible to lift this restriction by calling
1429/// [`anywhere`](ParseAny::anywhere) on the parser.
1430///
1431/// `check` argument is a function from any type `I` that implements `FromStr` to `T`.
1432/// Usually this should be `String` or `OsString`, but feel free to experiment. When
1433/// running `any` tries to parse an item on a command line into that `I` and applies the `check`
1434/// function. If the `check` succeeds - parser `any` succeeds and produces `T`, otherwise it behaves
1435/// as if it hasn't seen it. If `any` works in `anywhere` mode - it will try to parse all other
1436/// unconsumed items, otherwise, `any` fails.
1437///
1438/// # Use `any` to capture the remaining arguments
1439/// Normally you would use [`positional`] with [`strict`](ParsePositional::strict) annotation for
1440/// that, but using any allows you to blur the boundary between arguments for child process and self
1441/// process a bit more.
1442#[cfg_attr(not(doctest), doc = include_str!("docs2/any_simple.md"))]
1443///
1444/// # Use `any` to parse a non standard flag
1445///
1446#[cfg_attr(not(doctest), doc = include_str!("docs2/any_switch.md"))]
1447///
1448/// # Use `any` to parse a non standard argument
1449/// Normally `any` would try to display itself as a usual metavariable in the usage line and
1450/// generated help, you can customize that with [`metavar`](ParseAny::metavar) method:
1451///
1452#[cfg_attr(not(doctest), doc = include_str!("docs2/any_literal.md"))]
1453///
1454/// # See also
1455/// [`literal`] - a specialized version of `any` that tries to parse a fixed literal
1456#[must_use]
1457pub fn any<I, T, F>(metavar: &str, check: F) -> ParseAny<T>
1458where
1459    I: FromStr + 'static,
1460    F: Fn(I) -> Option<T> + 'static,
1461    <I as std::str::FromStr>::Err: std::fmt::Display,
1462{
1463    ParseAny {
1464        metavar: [(metavar, Style::Metavar)][..].into(),
1465        help: None,
1466        check: Box::new(move |os: std::ffi::OsString| {
1467            match crate::from_os_str::parse_os_str::<I>(os) {
1468                Ok(v) => check(v),
1469                Err(_) => None,
1470            }
1471        }),
1472
1473        anywhere: false,
1474    }
1475}
1476
1477/// A specialized version of [`any`] that consumes an arbitrary string
1478///
1479/// By default `literal` behaves similarly to [`positional`] so you should be using it near the
1480/// rightmost end of the consumer struct and it will only try to parse the first unconsumed
1481/// item on the command line. It is possible to lift this restriction by calling
1482/// [`anywhere`](ParseAny::anywhere) on the parser.
1483///
1484#[cfg_attr(not(doctest), doc = include_str!("docs2/any_literal.md"))]
1485///
1486/// # See also
1487/// [`any`] - a generic version of `literal` that uses function to decide if value is to be parsed
1488/// or not.
1489#[must_use]
1490pub fn literal(val: &'static str) -> ParseAny<()> {
1491    any("", move |s: String| if s == val { Some(()) } else { None })
1492        .metavar(&[(val, crate::buffer::Style::Literal)][..])
1493}
1494
1495/// Strip a command name if present at the front when used as a `cargo` command
1496///
1497// this is exactly the same as batteries::cargo_helper, but used by derive macro...
1498#[must_use]
1499#[doc(hidden)]
1500pub fn cargo_helper<P, T>(cmd: &'static str, parser: P) -> impl Parser<T>
1501where
1502    T: 'static,
1503    P: Parser<T>,
1504{
1505    let skip = literal(cmd).optional().hide();
1506    construct!(skip, parser).map(|x| x.1)
1507}
1508
1509/// Choose between several parsers specified at runtime
1510///
1511/// You can use this function to create multiple parsers that produce the same type of value at a runtime
1512/// and let bpaf to pick one that best fits best. This function is designed to work in Combinatoric
1513/// API, but you can use it in Derive API with `extern`.
1514///
1515#[cfg_attr(not(doctest), doc = include_str!("docs2/choice.md"))]
1516pub fn choice<T: 'static>(parsers: impl IntoIterator<Item = Box<dyn Parser<T>>>) -> impl Parser<T> {
1517    let mut parsers = parsers.into_iter();
1518    let mut this = match parsers.next() {
1519        None => return fail("Invalid choice usage").boxed(),
1520        Some(p) => p,
1521    };
1522    for that in parsers {
1523        this = Box::new(ParseOrElse { this, that })
1524    }
1525    this
1526}