cmd-args

Command line argument parser with nested command support

2 unstable releases

0.2.0 Mar 15, 2020
0.1.0 Mar 13, 2020


Used in vault-cli

MIT license

39KB
713 lines

cmd-args Command line parser for Rust

cmd-args is a command line parser for Rust, which can be used to build command line interfaces easily.

Introduction

You might have noticed that in the rust-ecosystem there are plenty of command line parser solutions available by now, so why bother and write another? I started this project because I was writing a small Rust program in order to learn Rust. For this project I ended up needing a command line parser and thought that it would not hurt to just try writing one by myself. It ended up working just fine, thus it is now available here for others who might enjoy using it.

Concepts

Command context (Group)

The command line parser is parsing a command context (for example for the call scoop bucket add the command context would be the sub-command add of the bucket command of the program scoop). That context is used to determine the anticipated/allowed options and arguments the command is taking. The struct in the library used to define a command context is called Group.

Options (Flags are also options!)

For cmd-args options are all optional arguments which have one or multiple - characters as prefix. That means flags are options with boolean type.

The parser will not care how many - chars you specify, so -?, --? and --------? will be the interpreted the same.

When having multiple sub-commands all involved options on the command context path from the root Group to the leaf Group are accepted. For example when having an app accepting scoop bucket add, which means three levels (Root, intermediate and leaf), will accept all options specified on the root Group scoop, the intermediate level Group bucket and the leaf level Group add.

Arguments

Arguments are defined by the current command context. When calling for example a app scoop bucket add and the command context (Group) for add takes one argument, then the whole call only accepts one argument (Compare with options where for each command context (Group) level the options are accepted).

Features

Nested commands (Groups)

You might want to build a CLI with nested commands meaning commands which have sub-commands, which may have sub-commands, which may have sub-commands, ... (You see where this going!).

Take for example a CLI application named store which does have sub-commands shelve, staff, .... When using sub-command shelve we have another three sub-commands list, add, remove to list all available shelves, add another shelve, remove a shelve.

These are nested commands! You can go creative and define arbitrarily nested CLIs!

Generated help

Command line interfaces most likely have a documentation available when calling them using the --help or -? flag. That one is automatically generated from the command specification!

Sub-command and option aliases

The library supports aliasing sub-commands and options which will as well appear in the auto-generated help documentation.

Example

More examples coming soon in the repositories example directory!

let group = Group::new(Box::new(|args, options| {
    let test_argument = args[0].str().unwrap();
    let the_truth = options.get("the-truth").unwrap().int().unwrap();

    println!("Hello from root command with test argument value '{}' and the_truth = '{}'", test_argument, the_truth);
}), "Simple CLI tool")
    .add_option(option::Descriptor::new("the-truth", option::Type::Int { default: 42 }, "The truth about everything"))
    .add_argument(arg::Descriptor::new(arg::Type::Str, "Test text"))
    .add_child("subcommand", None, Group::new(Box::new(|args, options| {
        println!("Hello from subcommand!");
    }), "A sub command!"));

parser::parse(group, None).unwrap();

No runtime deps