Pirate Build Status

A command-line arrrrguments parser, written in Rust.

Synopsis

Most programs that provide a command-line interface use a special-purpose library to make the process easier, such as the GNU Project's getopt library. The Rust team provides their own alternative, getoptions, which deserves an award for the Most Originally Named Project Ever.

In all seriousness, getoptions is a fantastic library that gives the developers all of the power necessary to create and interface with command-line arguments. However, with all that power comes complexity. getoptions -- while straight forward to use -- is verbose. The developer has to call different functions repeatedly in order to add different command-line options to their programs. While the only victim here is the developer's wrists due to carpal tunnel, I felt that there was a better way to do things.

Enter Pirate (which should totally usurp getoptions for the award of Most Originally Named Project Ever).

Installation

Add this to your project's Cargo.toml file:

[dependencies] pirate = "1.0.0"

and this to your crate root:

rust extern crate pirate;

Usage

Using Pirate is simple. First, create a vector defining all of the valid options that your program accepts:

rust let options = vec![ "a/addend#The right side of the addition equation; default=1:", "#Required Arguments", ":augend#The left side of an addition equation" ];

Options are defined in a very specific format:

Next, create a Vars struct, which is responsible for keeping track of all of the options, along with the program's name, defined for the program:

rust let vars: Vars = match pirate::vars("program-name", &options) { Ok(v) => v, Err(why) => panic!("Error: {}", why) }

Next, call the pirate::matches() function, passing in a vector of the program's environment arguments, along with a mutable reference to the Vars struct that you previously defined:

rust let matches: Matches = match pirate::matches(env::args().collect(), &mut vars) { Ok(m) => m, Err(why) => { println!("Error: {}", why); pirate::usage(&vars); return; } } Matches is nothing more than a type alias to a HashMap<String, String>. All of the custom methods that make the type easier to use are defined by the Match trait.

And finally, check which arguments were passed to the program.

``` // Returns a reference to the given arg, or None if not found fn get(arg: &str) -> Option<&String>;

// Returns true if the match exists, false if not fn has_match(arg: &str) -> bool;

// An iterator over all matches found fn keys() -> Keys; ```

Something to remember when using the get() function: by default, the pirate::matches() function stores the opt's long-form name as the key, by default, should the long-form exist; otherwise the short-form is used. So, should you define an opt with both a short- and long-form name, when querying for it, pass the long-form as the argument. For example:

```rust let options = vec!["l/long#An example opt"]; let vars = pirate::vars("program-name", &options); let matches = pirate::matches(&env::args().collect(), &mut vars).unwrap();

let short = matches.get("l").unwrap(); // Error! This won't work! let long = matches.get("long").unwrap(); // Success!

// Usage: program-name -l ```

As shown in a previous example, should you ever want to display the program's usage data, simply call the pirate::usage() function, passing in a reverence to your Vars struct as an argument. E.g. pirate::usage(&vars)

Example

Here is a trivial example that gives a general idea about how to use pirate:

```rust extern crate pirate;

use pirate::{Matches, Match, matches, usage, vars};

fn main() { let env_args: Vec = vec![ String::from("test"), String::from("-a"), String::from("2"), String::from("3") ]; let options = vec![ "a/addend#The right side of the addition equation; default=1:", "#Required Arguments", ":augend#The left side of an addition equation" ]; let mut vars = vars("test", &options).unwrap();

let matches: Matches = match matches(&env_args, &mut vars) {
    Ok(m) => m,
    Err(why) => {
        println!("Error: {}", why);
        usage(&vars);
        return;
    }
};

if matches.has_match("help") {
    usage(&vars);
    return;
}

let augend: i32 = matches.get("augend")
                    .unwrap()
                    .parse::<i32>()
                    .unwrap();

let addend: i32 = match matches.get("addend") {
    Some(a) => a.parse::<i32>().unwrap(),
    None => 1
};

let sum = augend + addend;

println!("{} + {} = {}", augend, addend, sum);

} ```

License

Pirate is licensed under the GNU Lesser General Public License, v3.