Expand description
§Introduction
rags
is an easy to use argument parsing library that provides pretty help-printing.
The library allows defining arguments in the same tree-like manner that users and developers expect. This leads to efficient parsing as we can efficiently eliminate work based on the state of the parsing. Once an argument has been matched it will never be inspected again.
rags
also makes liberal use of the From<String>
trait so that arguments
can be parsed into any complex type. This means, for example, that an argument
naming a file can be constructed directly into a struct wrapping std::fs::File
.
This leads to re-usable code between subcommands and developers can spend less time
and effort inspecting args.
Arguments in the same level (it’s tree-like) are parsed in the order in which they are defined. This means that global args are easy and provides both argument and semantic isolation between subcommands. Once a branch in the parse tree is taken (subcommand), the parser will not consider arguments defined “after” that branch in a higher scope. Because nested subcommands always lead to a lower scope, all arguments along that parse path are considered. This leads to 2 basic rules of usage:
- global arguments should always be declared first
- positional arguments should be defined within a subcommand scope even if shared betwwen subcommands
§Example Usage
Below is an example of usage that tries to capture most features an concepts.
While this had to be edited to match Rust’s doctest requirements, the examples
directory contains examples which follow best practices in a “real” application
such as defining descriptions as static, not returning errors from main
, etc.
extern crate rags_rs as rags;
#[derive(Debug)]
pub struct Options {
debug: bool,
verbosity: usize,
subcmds: Vec<String>,
build_release: bool,
build_link: Vec<String>,
package: String,
dry_run: bool,
initial_file: String,
additional_files: Vec<String>,
}
impl Default for Options {
fn default() -> Options {
Options {
debug: false,
verbosity: 0,
subcmds: vec!(),
build_release: false,
build_link: vec!(),
package: "main".to_string(),
dry_run: false,
initial_file: "".to_string(),
additional_files: vec!(),
}
}
}
fn main() -> Result<(), rags::Error> {
let long_desc: &'static str =
"This example aims to show beginner to intermediate options on the parser
as well as good practices.
As such, the usefulness of the binary is minimal but it will show you how
an application should be structured, options passed, errors handled, and
using parser state to control execution flow (print_help+exit, subcommands, etc).";
let mut opts = Options::default();
let mut parser = rags::Parser::from_args();
parser
.app_desc("example using most rags features")
.app_long_desc(long_desc)
.group("logging", "adjust logging output")?
.flag('D', "debug", "enter debug mode", &mut opts.debug, false)?
.count('v', "verbose", "increase vebosity (can be given multiple times)",
&mut opts.verbosity, 1)?
.done()?
.subcommand("build", "build a target", &mut opts.subcmds, None)?
.arg('p', "package", "rename the package", &mut opts.package, Some("PKG"), true)?
.list('l', "lib", "libraries to link", &mut opts.build_link, Some("LIB"), false)?
.long_flag("release", "do a release build", &mut opts.build_release, false)?
.positional("file", "file to build", &mut opts.initial_file, true)?
.positional_list("files", "additional files to build",
&mut opts.additional_files, false)?
.done()?
.subcommand("clean", "clean all build artifacts", &mut opts.subcmds, None)?
.flag('p', "print-only", "print what files would be cleaned, but do not clean",
&mut opts.dry_run, false)?
.done()?
;
if parser.wants_help() {
parser.print_help();
} else {
println!("final config: {:?}", opts);
}
Ok(())
}
§Example Help Dialog
The above example prints the following under various help requests:
§Root Command Help
$ rags --help
rags - 0.1.0 - example using most rags features
usage: rags {subcommand} [-Dv]
This example aims to show beginner to intermediate options on the parser
as well as good practices.
As such, the usefulness of the binary is minimal but it will show you how
an application should be structured, options passed, errors handled, and
using parser state to control execution flow (print_help+exit, subcommands, etc).
subcommands:
build build a target
clean clean all build artifacts
logging: adjust logging output
-D, --debug enter debug mode [default: false]
-v, --verbose increase vebosity (can be given multiple times) [default: 0]
§Subcommand Help
Notice that in the subcommand help we still see the global arguments.
$ rags build --help
rags build - 0.1.0 - build a target
usage: rags build [-Dv -l LIB --release] -p PKG file [files...]
logging: adjust logging output
-D, --debug enter debug mode [default: false]
-v, --verbose increase vebosity (can be given multiple times) [default: 0]
options:
-p, --package PKG rename the package [required, default: main]
-l, --lib LIB libraries to link
--release do a release build [default: false]
positionals:
file file to build [required]
files... additional files to build
Re-exports§
pub use errors::*;
Modules§
Macros§
- Helper macro to populate the application name, version, and description from the Cargo manifest. Metadata setter functions can be called multiple times if only some of this information is specified in the manifest.
Structs§
- Parser holds the state required for parsing. The methods provided here define how arguments should be treated as well as where they are constructed.
- Unused carries information about arguments which go unmatched. Used both in delineating short-code runs as well as passing back all unmatched arguments to the user (when requested via Parser::unused).
Enums§
- Defines the types of arguments we can handle, and when matched, our best guess as to what kind of arg that is until we can verify with more context.