Rust does not include flag/option/argument parsing functionality in its standard library, and this is probably sensible because it's quite specific functionality (not all software is CLI software), and there's a lot of variation in how people want their argument parsing libraries to work, in feature set, style of arguments for users, and style of library API.
Here are some notes on some existing Rust argument parsing libraries:
clap
clap
(version 2.x).
- Very widely used. (Cargo uses it I think?)
- Lots of features: Auto-generated help. Coloured terminal output. Complex validation, e.g., you can specify that some arguments are mutually exclusive. Can auto-suggest spelling corrections for unknown flags. Supports non-UTF-8 argument values. Supports sub-commands.
- API is based on building a runtime structure that describes your program/command's flags; i.e., you call a bunch of nested functions to describe your flags. You can also load that metadata/configuration from a YAML file.
- The result of parsing arguments is a dynamic structure that you query.
It uses unsafe
to transmute
&[u8]
to &OsStr
on Windows, which is the subject of #1594 and #1524.
This version of clap primarily relies on building a structure at runtime to describe your program's arguments. This can lead to quite a lot of boilerplate and duplicated structure if you want to parse arguments and then put them into a structured form.
Conclusion: If you don't care about unsafe (or you're not on Windows at all), and you don't care about size, compile time or any other "bloat" metric, and you don't care about fairly large boilerplate, then clap
is fine. It does everything.
clap-v3
Rewrite(?) of clap
. I haven't used it. I believe it has different ergonomics. They have also eliminated the use of unsafe
, which is good to see.
pico-args
Opposite end of the spectrum from clap
. pico-args
primarily advertises itself by small feature-set, fast compile time, small binary code size, no dependencies. Unlike the others, pico-args doesn't have any structure (runtime or static) that describes your full argument set.
Instead, it basically provides some parsing functions to take an argument array and extract/test for individual values and flags. You can dump the results into your own structure or use them in some other ways. It has some possibly strange restrictions (restrictions that you will probably only realise if you read the docs carefully). Things like: "Must be used only once for each flag." on some of the parsing functions. So it's fine if you use it following the particular code structure in the example(s) but if you structure things differently it might not work the way you expect.
Does not have any fancy features. Cannot auto-generate docs/help output for you.
Explicitly marked with [forbid(unsafe_code)]
. The whole implementation including comments and whitespace is about 800 lines.
Supports OsStr/non-utf8 flags, with some limitations - in particular if you're using =
separated flag values (e.g., --someflag=somevalue
) then non-Unicode values will prevent the flag from matching (e.g., if somevalue
was actually not a valid UTF-8 string).
Conclusion: Seems ok for what it does, but rather limited.
gumdrop
Intermediate feature-set. gumdrop
is built around a proc-macro derive thingy, and the argument schema is described by annotating structs with flag names, help messages and so on. It is significantly slimmer than clap
. Generates help output for you (unlike pico-args
) but doesn't do really fancy things like colourized output or suggesting typo-fixes for unknown flags.
Does not support OsStr/non-Unicode arguments. No uses of unsafe
.
Conclusion: I like gumdrop. I would like it more if it supported OsStr arguments, simply because I think missing that support is an annoying rough edge. I think the feature set is pretty good; it does enough to be really useful, without including everything-and-the-kitchen-sink like clap
does.
argh
argh
.
This seems to just be the same as gumdrop
in its feature set and design. Annotate structs, flags are derived from that.
argh
was written by someone on the Fuchsia OS team (or something) within Google, so touching it requires submitting a Contributor License Agreement. Code was dumped into github in one block at some point.
Conclusion: Use gumdrop instead, unless you're working on Fuchsia.