Struct bpaf::params::ParseAny

source ·
pub struct ParseAny<T> { /* private fields */ }
Expand description

Parse the next available item on a command line with no restrictions, created with any.

Implementations§

Add a help message to any parser.

Combinatoric usage
#[derive(Debug, Clone)]
pub struct Options {
    turbo: bool,
    rest: Vec<OsString>,
}

pub fn options() -> OptionParser<Options> {
    let turbo = short('t')
        .long("turbo")
        .help("Engage the turbo mode")
        .switch();
    let rest = any::<OsString>("REST")
        .help("app will pass anything unused to a child process")
        .guard(|x| x != "--help", "keep help")
        .many();
    construct!(Options { turbo, rest }).to_options()
}
Derive usage
#[derive(Debug, Clone, Bpaf)]
#[bpaf(options)]
pub struct Options {
    #[bpaf(short, long)]
    /// Engage the turbo mode
    turbo: bool,
    #[bpaf(any("REST"), guard(not_help, "keep help"), many)]
    /// app will pass anything unused to a child process
    rest: Vec<OsString>,
}

fn not_help(s: &OsString) -> bool {
    s != "--help"
}
Examples

Capture --turbo flag for internal use and return everything else as is so it can be passed to some other program. Anything except for --turbo here and in following examples is consumed by any

% app --turbo git commit -m "hello world"
Options { turbo: true, rest: ["git", "commit", "-m", "hello world"] }

Or just capture and return everything

% app git commit -m "hello world"
Options { turbo: false, rest: ["git", "commit", "-m", "hello world"] }

Doesn’t have to be in order either

% app git commit -m="hello world" --turbo
Options { turbo: true, rest: ["git", "commit", "-m=hello world"] }

You can keep --help working, but you need to add extra guard for that

% app --turbo --help
Usage: [-t] <REST>...

Available positional items:
    <REST>  app will pass anything unused to a child process

Available options:
    -t, --turbo  Engage the turbo mode
    -h, --help   Prints help information
Examples found in repository?
examples/find.rs (line 45)
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
fn exec() -> impl Parser<Option<Vec<OsString>>> {
    let tag = any::<String>("-exec")
        .help("-exec /path/to/command flags and options ;")
        .guard(|s| s == "-exec", "not find");
    let item = any::<OsString>("ITEM")
        .guard(|s| s != ";", "not word")
        .many()
        .catch()
        .hide();
    let endtag = any::<String>("END").guard(|s| s == ";", "not eot").hide();
    construct!(tag, item, endtag)
        .anywhere()
        .map(|triple| triple.1)
        .optional()
        .catch()
}

/// parses symbolic permissions `-perm -mode`, `-perm /mode` and `-perm mode`
fn perm() -> impl Parser<Option<Perm>> {
    fn parse_mode(input: &str) -> Result<Perms, String> {
        let mut perms = Perms::default();
        for c in input.chars() {
            match c {
                'r' => perms.read = true,
                'w' => perms.write = true,
                'x' => perms.exec = true,
                _ => return Err(format!("{} is not a valid permission string", input)),
            }
        }
        Ok(perms)
    }

    let tag = any::<String>("-mode").help("-mode (perm | -perm | /perm)");
    let mode = any::<String>("mode")
        .parse::<_, _, String>(|s| {
            if let Some(m) = s.strip_prefix('-') {
                Ok(Perm::All(parse_mode(m)?))
            } else if let Some(m) = s.strip_prefix('/') {
                Ok(Perm::Any(parse_mode(m)?))
            } else {
                Ok(Perm::Exact(parse_mode(&s)?))
            }
        })
        .hide();

    construct!(tag, mode)
        .anywhere()
        .map(|pair| pair.1)
        .optional()
        .catch()
}
More examples
Hide additional examples
examples/dd.rs (line 23)
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
fn tag<T>(name: &'static str, meta: &'static str, help: &'static str) -> impl Parser<T>
where
    T: FromStr,
    <T as std::str::FromStr>::Err: std::fmt::Display,
{
    // it is possible to parse OsString here and strip the prefix with os_str_bytes or a similar
    // crate
    any::<String>(meta)
        .help(help)
        .parse::<_, _, String>(move |s| match s.strip_prefix(name) {
            None => Err("Wrong tag".to_string()),
            Some(body) => T::from_str(body).map_err(|e| e.to_string()),
        })
        .anywhere()
}
examples/xorg.rs (line 13)
11
12
13
14
15
16
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
fn toggle_options(name: &'static str, help: &'static str) -> impl Parser<bool> {
    any::<String>(name)
        .help(help)
        .parse(move |s| {
            let (state, cur_name) = if let Some(rest) = s.strip_prefix('+') {
                (true, rest)
            } else if let Some(rest) = s.strip_prefix('-') {
                (false, rest)
            } else {
                return Err(format!("{} is not a toggle option", s));
            };
            if cur_name != name {
                Err(format!("{} is not a known toggle option name", cur_name))
            } else {
                Ok(state)
            }
        })
        .anywhere()
}

fn extension() -> impl Parser<(String, bool)> {
    let on = any::<String>("+ext")
        .help("enable ext <EXT>")
        .parse::<_, _, String>(|s| {
            if s == "+ext" {
                Ok(true)
            } else {
                Err(String::new())
            }
        });
    let off = any::<String>("-ext")
        .help("disable ext <EXT>")
        .parse::<_, _, String>(|s| {
            if s == "-ext" {
                Ok(false)
            } else {
                Err(String::new())
            }
        });

    let state = construct!([on, off]);
    let name = positional::<String>("EXT").hide();
    construct!(state, name).map(|(a, b)| (b, a)).anywhere()
}

Trait Implementations§

Consume zero or more items from a command line and collect them into Vec Read more
Consume one or more items from a command line Read more
Turn a required argument into optional one Read more
Apply a failing transformation to a contained value Read more
Apply a pure transformation to a contained value Read more
Validate or fail with a message Read more
Use this value as default if value isn’t present on a command line Read more
Use value produced by this function as default if value isn’t present Read more
Ignore this parser during any sort of help generation Read more
Ignore this parser when generating usage line Read more
Attach help message to a complex parser Read more
Dynamic shell completion Read more
Static shell completion Read more
Add extra annotations to completion information Read more
Automagically restrict the inner parser scope to accept adjacent values only Read more
Parse anywhere Read more
Transform Parser into OptionParser to attach metadata and run Read more

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

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

The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.