bpaf::parsers

Struct ParseFallback

source
pub struct ParseFallback<P, T> { /* private fields */ }
Expand description

Parser that substitutes missing value but not parse failure, created with fallback.

Implementations§

source§

impl<P, T: Display> ParseFallback<P, T>

source

pub fn display_fallback(self) -> Self

Show fallback value in --help using Display representation

Combinatoric example
#[derive(Debug, Clone)]
pub struct Options {
    jobs: usize,
}

pub fn options() -> OptionParser<Options> {
    let jobs = long("jobs")
        .help("Number of jobs")
        .argument("JOBS")
        .fallback(42)
        .display_fallback();
    construct!(Options { jobs }).to_options()
}

fn main() {
    println!("{:?}", options().run())
}
Derive example
#[derive(Debug, Clone, Bpaf)]
#[bpaf(options)]
#[allow(dead_code)]
pub struct Options {
    /// Number of jobs
    #[bpaf(argument("JOBS"), fallback(42), display_fallback)]
    jobs: usize,
}

fn main() {
    println!("{:?}", options().run())
}
Output

fallback changes parser to fallback to a default value used when argument is not specified

$ app
Options { jobs: 42 }

If value is present - fallback value is ignored

$ app --jobs 10
Options { jobs: 10 }

Parsing errors are preserved and preserved to user

$ app --jobs ten
Error: couldn't parse ten: invalid digit found in string

With display_fallback and debug_fallback you can make it so default value is visible in --help output

$ app --help

Usage: app [--jobs=JOBS]

Available options:
--jobs=JOBS
Number of jobs
[default: 42]
-h, --help
Prints help information

Examples found in repository?
examples/dd.rs (line 34)
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
fn in_file() -> impl Parser<String> {
    tag::<String>("if=", "FILE", "read from FILE")
        .fallback(String::from("-"))
        .display_fallback()
}

fn out_file() -> impl Parser<String> {
    tag::<String>("of=", "FILE", "write to FILE")
        .fallback(String::from("-"))
        .display_fallback()
}

fn block_size() -> impl Parser<usize> {
    // it is possible to parse notation used by dd itself as well,
    // using usuze only for simplicity
    tag::<usize>("bs=", "SIZE", "read/write SIZE blocks at once")
        .fallback(512)
        .display_fallback()
}
More examples
Hide additional examples
examples/basic.rs (line 41)
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
fn opts() -> OptionParser<Out> {
    // A flag, true if used in the command line. Can be required, this one is optional

    let debug = short('d') // start with a short name
        .long("debug") // also add a long name
        .help("Activate debug mode") // and a help message to use
        .switch(); // turn this into a switch

    // number of occurrences of the v/verbose flag capped at 3 with an error here but you can also
    // use `max` inside `map`
    let verbose = short('v')
        .long("verbose")
        .help("Increase the verbosity\n You can specify it up to 3 times\n either as -v -v -v or as -vvv")
        .req_flag(())
        .many()
        .map(|xs| xs.len())
        .guard(|&x| x <= 3, "It doesn't get any more verbose than this");

    // an argument, parsed and with default value
    let speed = short('s')
        .long("speed")
        .help("Set speed")
        .argument::<f64>("SPEED") // you can specify a type to parse
        .fallback(42.0)
        .display_fallback();

    let output = short('o')
        .long("output")
        .help("output file")
        .argument::<PathBuf>("OUTPUT") // but it's optional when rustc can derive it
        .complete_shell(ShellComp::File { mask: None });

    // no magical name transmogrifications in combinatoric API,
    let nb_cars = short('n')
        .long("nb-cars")
        .help("Number of items to process")
        .argument::<u32>("N")
        .fallback(1)
        .display_fallback();

    // a parser that consumes one argument
    // you can build the inner parser in one go or as multiple steps giving each step a name
    // you can also add some static shell completion functionality
    let file_to_proces = short('f')
        .long("file")
        .help("File to process")
        .argument::<PathBuf>("FILE")
        .complete_shell(ShellComp::File { mask: Some("*.rs") });

    let files_to_process = file_to_proces.many();

    // packing things in a struct assumes parser for each field is in scope.
    construct!(Out {
        debug,
        verbose,
        speed,
        output,
        nb_cars,
        files_to_process
    })
    .to_options()
    .descr("This is a description")
}
source§

impl<P, T: Debug> ParseFallback<P, T>

source

pub fn debug_fallback(self) -> Self

Show fallback value in --help using Debug representation

Combinatoric example
fn try_to_get_version() -> Result<usize, &'static str> {
    Ok(42)
}

#[derive(Debug, Clone)]
pub struct Options {
    version: usize,
}

pub fn options() -> OptionParser<Options> {
    let version = long("version")
        .help("Specify protocol version")
        .argument("VERS")
        .fallback_with(try_to_get_version)
        .debug_fallback();
    construct!(Options { version }).to_options()
}

fn main() {
    println!("{:?}", options().run())
}
Derive example
fn try_to_get_version() -> Result<usize, &'static str> {
    Ok(42)
}

#[derive(Debug, Clone, Bpaf)]
#[bpaf(options)]
pub struct Options {
    #[bpaf(argument("VERS"), fallback_with(try_to_get_version), debug_fallback)]
    /// Specify protocol version
    version: usize,
}

fn main() {
    println!("{:?}", options().run())
}
Output

fallback_with changes parser to fallback to a value that comes from a potentially failing computation when argument is not specified

$ app
Options { version: 42 }

If value is present - fallback value is ignored

$ app --version 10
Options { version: 10 }

Parsing errors are preserved and preserved to user

$ app --version ten
Error: couldn't parse ten: invalid digit found in string

bpaf encases parsers with fallback value of some sort in usage with []

$ app --help

Usage: app [--version=VERS]

Available options:
--version=VERS
Specify protocol version
[default: 42]
-h, --help
Prints help information

Examples found in repository?
examples/coreutils.rs (line 74)
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
    pub fn parse_binary() -> impl Parser<bool> {
        #[derive(Debug, Clone, Copy, Bpaf, Eq, PartialEq)]
        enum Mode {
            /// Use binary mode
            #[bpaf(short, long)]
            Binary,
            /// Use text mode
            #[bpaf(short, long)]
            Text,
        }
        mode()
            .last()
            .fallback(Mode::Text)
            .debug_fallback()
            .map(|mode| mode == Mode::Binary)
    }

Trait Implementations§

source§

impl<P, T> Parser<T> for ParseFallback<P, T>
where P: Parser<T>, T: Clone,

source§

fn many(self) -> ParseMany<Self>
where Self: Sized,

Consume zero or more items from a command line and collect them into a Vec Read more
source§

fn collect<C>(self) -> ParseCollect<Self, C, T>
where C: FromIterator<T>, Self: Sized,

Transform parser into a collection parser Read more
source§

fn some(self, message: &'static str) -> ParseSome<Self>
where Self: Sized + Parser<T>,

Consume one or more items from a command line and collect them into a Vec Read more
source§

fn optional(self) -> ParseOptional<Self>
where Self: Sized + Parser<T>,

Turn a required argument into an optional one Read more
source§

fn count(self) -> ParseCount<Self, T>
where Self: Sized + Parser<T>,

Count how many times the inner parser succeeds, and return that number. Read more
source§

fn last(self) -> ParseLast<Self>
where Self: Sized + Parser<T>,

Apply the inner parser as many times as it succeeds, return the last value Read more
source§

fn parse<F, R, E>(self, f: F) -> ParseWith<T, Self, F, E, R>
where Self: Sized + Parser<T>, F: Fn(T) -> Result<R, E>, E: ToString,

Apply a failing transformation to a contained value Read more
source§

fn map<F, R>(self, map: F) -> ParseMap<T, Self, F, R>
where Self: Sized + Parser<T>, F: Fn(T) -> R + 'static,

Apply a pure transformation to a contained value Read more
source§

fn guard<F>(self, check: F, message: &'static str) -> ParseGuard<Self, F>
where Self: Sized + Parser<T>, F: Fn(&T) -> bool,

Validate or fail with a message Read more
source§

fn fallback(self, value: T) -> ParseFallback<Self, T>
where Self: Sized + Parser<T>,

Use this value as default if the value isn’t present on a command line Read more
source§

fn fallback_with<F, E>(self, fallback: F) -> ParseFallbackWith<T, Self, F, E>
where Self: Sized + Parser<T>, F: Fn() -> Result<T, E>, E: ToString,

Use value produced by this function as default if the value isn’t present Read more
source§

fn hide(self) -> ParseHide<Self>
where Self: Sized + Parser<T>,

Ignore this parser during any sort of help generation Read more
source§

fn hide_usage(self) -> ParseUsage<Self>
where Self: Sized + Parser<T>,

Ignore this parser when generating a usage line Read more
source§

fn custom_usage<M>(self, usage: M) -> ParseUsage<Self>
where M: Into<Doc>, Self: Sized + Parser<T>,

Customize how this parser looks like in the usage line Read more
source§

fn group_help<M: Into<Doc>>(self, message: M) -> ParseGroupHelp<Self>
where Self: Sized + Parser<T>,

Attach a help message to a complex parser Read more
source§

fn with_group_help<F>(self, f: F) -> ParseWithGroupHelp<Self, F>
where Self: Sized + Parser<T>, F: Fn(MetaInfo<'_>) -> Doc,

Make a help message for a complex parser from its MetaInfo Read more
source§

fn complete<M, F>(self, op: F) -> ParseComp<Self, F>
where M: Into<String>, F: Fn(&T) -> Vec<(M, Option<M>)>, Self: Sized + Parser<T>,

Available on crate feature autocomplete only.
Dynamic shell completion Read more
source§

fn complete_shell(self, op: ShellComp) -> ParseCompShell<Self>
where Self: Sized + Parser<T>,

Available on crate feature autocomplete only.
Static shell completion Read more
source§

fn to_options(self) -> OptionParser<T>
where Self: Sized + Parser<T> + 'static,

Transform Parser into OptionParser to get ready to run it Read more
source§

fn run(self) -> T
where Self: Sized + Parser<T> + 'static,

Finalize and run the parser Read more
source§

fn boxed(self) -> Box<dyn Parser<T>>
where Self: Sized + Parser<T> + 'static,

Create a boxed representation for a parser Read more

Auto Trait Implementations§

§

impl<P, T> Freeze for ParseFallback<P, T>
where P: Freeze, T: Freeze,

§

impl<P, T> RefUnwindSafe for ParseFallback<P, T>

§

impl<P, T> Send for ParseFallback<P, T>
where P: Send, T: Send,

§

impl<P, T> Sync for ParseFallback<P, T>
where P: Sync, T: Sync,

§

impl<P, T> Unpin for ParseFallback<P, T>
where P: Unpin, T: Unpin,

§

impl<P, T> UnwindSafe for ParseFallback<P, T>
where P: UnwindSafe, T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.