Function bpaf::pure

source ·
pub fn pure<T>(val: T) -> ParsePure<T>
Expand description

Parser that produces a fixed value

This parser produces T without consuming anything from the command line, which can be useful with construct!. As with any parsers, T should be Clone and Debug.

Both pure and pure_with are designed to put values into structures, to generate fallback you should be using fallback and fallback_with.

See also pure_with for a pure computation that can fail.

Combinatoric example
#[derive(Debug, Clone)]
pub struct Options {
    name: String,
    money: u32,
}

pub fn options() -> OptionParser<Options> {
    // User can customise a name
    let name = long("name").help("Use a custom user name").argument("NAME");
    // but not starting amount of money
    let money = pure(330);
    construct!(Options { name, money }).to_options()
}

fn main() {
    println!("{:?}", options().run())
}
Derive example
#[derive(Debug, Clone, Bpaf)]
#[bpaf(options)]
pub struct Options {
    #[bpaf(argument("NAME"))]
    /// Use a custom user name
    name: String,
    #[bpaf(pure(330))]
    money: u32,
}

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

pure does not show up in --help message

$ app --help

Usage: app --name=NAME

Available options:
--name=NAME
Use a custom user name
-h, --help
Prints help information

And there’s no way to alter the value from the command line

$ app --name Bob
Options { name: "Bob", money: 330 }

Any attempts to do so would result in an error :)

$ app --money 100000 --name Hackerman
Error: --money is not expected in this context
Examples found in repository?
examples/dynamic-tree.rs (line 67)
61
62
63
64
65
66
67
68
69
70
71
72
73
74
fn make_parser(item: &Cog) -> Box<dyn Parser<&'static str>> {
    match item {
        Cog::Command {
            help,
            name,
            operation,
        } => Box::new(pure(*operation).to_options().descr(*help).command(name)),
        Cog::Group { name, help, nested } => {
            let nested = nested.iter().map(make_parser).collect::<Vec<_>>();
            let inner = choose(nested);
            inner.to_options().descr(*help).command(name).boxed()
        }
    }
}
More examples
Hide additional examples
examples/dynamic.rs (line 59)
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
fn main() {
    let items = &[
        ("banana", Ty::Bool),
        ("width", Ty::Number),
        ("name", Ty::String),
    ];

    let mut parser = pure(Vec::<(String, Value)>::new()).boxed();
    for (name, ty) in items {
        parser = cons(
            parser,
            match ty {
                Ty::Bool => bool(name).boxed(),
                Ty::Number => number(name).boxed(),
                Ty::String => string(name).boxed(),
            },
        )
    }

    let options = parser.run();
    println!("{:?}", options);
}
examples/confusing.rs (line 37)
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
fn main() {
    let token = long("token")
        .help("Token used for complex commands")
        .argument::<String>("TOKEN")
        .optional();

    // start with defining 3 commands: simple, complex1 and complex2
    let simple_parser = pure(PreCommand::Simple).to_options();
    let simple = simple_parser.command("simple");

    let complex1_parser = positional::<i32>("ARG");
    let complex1 = construct!(PreCommand::Complex1(complex1_parser))
        .to_options()
        .descr("This is complex command 1")
        .command("complex1");

    let complex2_parser = positional::<i16>("ARG");

    let complex2 = construct!(PreCommand::Complex2(complex2_parser))
        .to_options()
        .descr("This is complex command 2")
        .command("complex2");

    // compose then to accept any of those
    let preparser = construct!([simple, complex1, complex2]);

    // make a parser that accepts optional token and one of incomplete commands
    // then create complete command or fail
    let parser = construct!(token, preparser).parse(|(token, cmd)| match cmd {
        PreCommand::Simple => Ok(Command::Simple),
        PreCommand::Complex1(a) => match token {
            Some(token) => Ok(Command::Complex1(token, a)),
            None => Err("You must specify token to use with --token"),
        },
        PreCommand::Complex2(a) => match token {
            Some(token) => Ok(Command::Complex2(token, a)),
            None => Err("You must specify token to use with --token"),
        },
    });

    let cmd = parser.to_options().run();
    println!("{:?}", cmd);
}