parkour

A fast, extensible, command-line arguments parser.

Documentation ยท Tests

Introduction ๐Ÿ“š

The most popular argument parser, clap, allows you list all the possible arguments and their constraints, and then gives you a dynamic, stringly-typed object containing all the values. Usually these values are then manually extracted into structs and enums to access the values more conveniently and get the advantages of a static type system (example).

Parkour uses a different approach: Instead of parsing the arguments into an intermediate, stringly-typed object, it parses them directly into the types you want, so there's no cumbersome conversion. For types outside the standard library, you need to implement a trait, but in most cases this can be done with a simple derive macro.

This has several advantages:

Status

Parkour started as an experiment and is very new (about 1 week old at the time of writing). Expect frequent breaking changes. If you like what you see, consider supporting this work by

Right now, parkour lacks some important features, which I intend to implement:

Example

```rust use parkour::prelude::*;

[derive(FromInputValue)]

enum ColorMode { Always, Auto, Never, }

struct Command { color_mode: ColorMode, file: String, }

impl FromInput for Command { type Context = ();

fn from_input<P: Parse>(input: &mut P, _: &Self::Context)
    -> Result<Self, parkour::Error> {
    // discard the first argument
    input.bump_argument().unwrap();

    let mut file = None;
    let mut color_mode = None;

    while !input.is_empty() {
        if input.parse_long_flag("help") || input.parse_short_flag("h") {
            println!("Usage: run [-h,--help] [--color,-c auto|always|never] FILE");
            return Err(parkour::Error::early_exit());
        }
        if SetOnce(&mut color_mode)
            .apply(input, &Flag::LongShort("color", "c").into())? {
            continue;
        }
        if SetPositional(&mut file).apply(input, &"FILE")? {
            continue;
        }
        input.expect_empty()?;
    }

    Ok(Command {
        color_mode: color_mode.unwrap_or(ColorMode::Auto),
        file: file.ok_or_else(|| parkour::Error::missing_argument("FILE"))?,
    })
}

} ```

Code of Conduct ๐Ÿค

Please be friendly and respectful to others. This should be a place where everyone can feel safe, therefore I intend to enforce the Rust code of conduct.

License

This project is licensed under either of

at your option.