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 presented to the user

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

With display_fallback, debug_fallback, and format_fallback, you can make it so the default value is visible in the --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)
31fn in_file() -> impl Parser<String> {
32    tag::<String>("if=", "FILE", "read from FILE")
33        .fallback(String::from("-"))
34        .display_fallback()
35}
36
37fn out_file() -> impl Parser<String> {
38    tag::<String>("of=", "FILE", "write to FILE")
39        .fallback(String::from("-"))
40        .display_fallback()
41}
42
43fn block_size() -> impl Parser<usize> {
44    // it is possible to parse notation used by dd itself as well,
45    // using usuze only for simplicity
46    tag::<usize>("bs=", "SIZE", "read/write SIZE blocks at once")
47        .fallback(512)
48        .display_fallback()
49}
More examples
Hide additional examples
examples/basic.rs (line 41)
17fn opts() -> OptionParser<Out> {
18    // A flag, true if used in the command line. Can be required, this one is optional
19
20    let debug = short('d') // start with a short name
21        .long("debug") // also add a long name
22        .help("Activate debug mode") // and a help message to use
23        .switch(); // turn this into a switch
24
25    // number of occurrences of the v/verbose flag capped at 3 with an error here but you can also
26    // use `max` inside `map`
27    let verbose = short('v')
28        .long("verbose")
29        .help("Increase the verbosity\n You can specify it up to 3 times\n either as -v -v -v or as -vvv")
30        .req_flag(())
31        .many()
32        .map(|xs| xs.len())
33        .guard(|&x| x <= 3, "It doesn't get any more verbose than this");
34
35    // an argument, parsed and with default value
36    let speed = short('s')
37        .long("speed")
38        .help("Set speed")
39        .argument::<f64>("SPEED") // you can specify a type to parse
40        .fallback(42.0)
41        .display_fallback();
42
43    let output = short('o')
44        .long("output")
45        .help("output file")
46        .argument::<PathBuf>("OUTPUT") // but it's optional when rustc can derive it
47        .complete_shell(ShellComp::File { mask: None });
48
49    // no magical name transmogrifications in combinatoric API,
50    let nb_cars = short('n')
51        .long("nb-cars")
52        .help("Number of items to process")
53        .argument::<u32>("N")
54        .fallback(1)
55        .display_fallback();
56
57    // a parser that consumes one argument
58    // you can build the inner parser in one go or as multiple steps giving each step a name
59    // you can also add some static shell completion functionality
60    let file_to_proces = short('f')
61        .long("file")
62        .help("File to process")
63        .argument::<PathBuf>("FILE")
64        .complete_shell(ShellComp::File { mask: Some("*.rs") });
65
66    let files_to_process = file_to_proces.many();
67
68    // packing things in a struct assumes parser for each field is in scope.
69    construct!(Out {
70        debug,
71        verbose,
72        speed,
73        output,
74        nb_cars,
75        files_to_process
76    })
77    .to_options()
78    .descr("This is a description")
79}
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 presented to the 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    pub fn parse_binary() -> impl Parser<bool> {
62        #[derive(Debug, Clone, Copy, Bpaf, Eq, PartialEq)]
63        enum Mode {
64            /// Use binary mode
65            #[bpaf(short, long)]
66            Binary,
67            /// Use text mode
68            #[bpaf(short, long)]
69            Text,
70        }
71        mode()
72            .last()
73            .fallback(Mode::Text)
74            .debug_fallback()
75            .map(|mode| mode == Mode::Binary)
76    }
Source§

impl<P, T> ParseFallback<P, T>

Source

pub fn format_fallback( self, format: impl Fn(&T, &mut Formatter<'_>) -> Result, ) -> Self

Show fallback value in --help using the provided formatting function.

Combinatoric example
use std::{fmt::Display as _, path::PathBuf};
#[derive(Debug, Clone)]
pub struct Options {
    log_file: PathBuf,
}

pub fn options() -> OptionParser<Options> {
    let log_file = long("log-file")
        .help("Path to log file")
        .argument::<PathBuf>("FILE")
        .guard(
            |log_file| !log_file.is_dir(),
            "The log file can't be a directory",
        )
        .fallback(PathBuf::from("logfile.txt"))
        .format_fallback(|path, f| path.display().fmt(f));
    construct!(Options { log_file }).to_options()
}

fn main() {
    println!("{:?}", options().run())
}
Derive example
use std::{fmt::Display as _, path::PathBuf};
#[derive(Debug, Clone, Bpaf)]
#[bpaf(options)]
#[allow(dead_code)]
pub struct Options {
    /// Path to log file
    #[bpaf(
        argument("FILE"),
        guard(|log_file| !log_file.is_dir(), "The log file can't be a directory"),
        fallback(PathBuf::from("logfile.txt")),
        format_fallback(|path, f| path.display().fmt(f)),
    )]
    log_file: PathBuf,
}

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

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

$ app
Options { log_file: "logfile.txt" }

If value is present - fallback value is ignored

$ app --log-file output.txt
Options { log_file: "output.txt" }

Parsing errors are preserved and presented to the user

$ app --log-file /
Error: /: The log file can't be a directory

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

$ app --help

Usage: app [--log-file=FILE]

Available options:
--log-file=FILE
Path to log file
[default: logfile.txt]
-h, --help
Prints help information

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.