Managing Program Flag Arguments With Getopts

The getopts crate provides a simple library for parsing command-line arguments given to the program. We will first be using this crate to determine whether or not we should disable colors, but will ultimately whether we should launch a graphical or command-line interface.

Lets start by adding getopts to our Cargo.toml and main.rs files.

Cargo.toml

getopts = "*"

main.rs

extern crate getopts;

Configuring and Parsing Flags

The absolute first thing that needs to be performed is to get a Vec of Strings containing a list of all the arguments that were supplied to the program. Inside the main() function, add the following at the very top:

let args: Vec<String> = std::env::args().collect();

Next we need to configure all of the flags that our program will accept. A flag is a command-line switch, such as -h or --help, which flags to our program what it should be trying to do.

We will first initialize a new getopts::Options and make it mutable so that we can add on all of the arguments that we want to use. For now, we will just define options for disabling colors and displaying a help message.

let mut opts = getopts::Options::new();
opts.optflag("n", "no-color", "prints without colors");
opts.optflag("h", "help", "show this information");

Next we will actually parse the list of arguments from our args variable with opts using the parse() method available to getopts::Options. We want to ignore the first variable in args though because, as with almost every other programming language, the first argument is the name of the running program. We can do this by passing &args[1..] to signify to skip the 0th variable.

let matches = opts.parse(&args[1..]).unwrap();

Finally we will check what was matched and perform actions based on that.

if matches.opt_present("h") { print_help(); return; } // Print help and exit
match matches.opt_present("n") {
    true => phoronix_cli::print(),
    false => phoronix_cli::print_colored(),
};

Adding a Help Function

You may have noticed that we are calling a print_help() function but we don't actually have a print_help() function. That's because we are going to do that right now.

fn print_help() {
    println!("Prints the latest information from Phoronix.");
    println!("    -h, --help     : show this information");
    println!("    -n, --no-color : prints without colors");
}

Example

extern crate hyper;
extern crate select;
extern crate term;
extern crate getopts;
mod article;
mod hompage;
mod linesplit;
mod phoronix_cli;

fn main() {
    let args: Vec<String> = std::env::args().collect();
    let mut opts = getopts::Options::new();
    opts.optflag("n", "no-color", "prints without colors");
    opts.optflag("h", "help", "show this information");
    let matches = opts.parse(&args[1..]).unwrap();
    if matches.opt_present("h") { print_help(); return; }
    match matches.opt_present("n") {
        true => phoronix_cli::print(),
        false => phoronix_cli::print_colored(),
    };
}

fn print_help() {
    println!("Prints the latest information from Phoronix.");
    println!("    -n, --no-color : prints without colors");
    println!("    -h, --help     : show this information");
}