cmd-args
is a command line parser for Rust, which can be used to build command line interfaces easily.
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.
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
.
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 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).
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!
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!
The library supports aliasing sub-commands and options which will as well appear in the auto-generated help documentation.
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();