Skip to main content

Crate getargs_derive

Crate getargs_derive 

Source
Expand description

§getargs-derive

crates.io docs.rs CI codecov License: MIT MSRV

A Clap-style #[derive] command-line argument parser for no_std and embedded Rust. Describe your CLI as a struct, and getargs-derive generates a zero-allocation parser on top of getargs, with compile-time help, subcommands, helpful errors and shell completions. If you know Clap’s derive API, you already know this one.

§Why getargs-derive?

  • no_std and no allocation by default. The parser only needs core: parsed values and errors borrow the arguments, and repeated values fit in fixed-capacity collections. It runs the same on a microcontroller, in a kernel or in a regular binary.
  • Help computed at compile time. --help, --version and the help of every subcommand are &'static str constants built by the macro, so no help-formatting code ends up in your binary.
  • Clap-familiar attributes. #[arg(short, long, default_value_t = ...)], doc comments as help text, #[derive(ValueEnum)], #[derive(Subcommand)], #[command(flatten)], env, conflicts_with, requires, argument groups, aliases, Count flags and more, with Clap’s help layout and error wording.
  • Helpful errors. Clap-style messages with “did you mean” suggestions for misspelled options and subcommands, and compile-time diagnostics for invalid attributes instead of runtime panics.
  • Shell completions and man pages. With the std feature, generate bash, zsh and fish completion scripts and a roff man page from the same struct.
  • Small dependency tree. At run time, only getargs, which has no dependencies itself, plus heapless if you enable it.
  • Non-UTF-8 arguments. Parse raw &[u8] arguments anywhere, and OsString/PathBuf fields with std.

§Installation

cargo add getargs-derive getargs

or in Cargo.toml:

[dependencies]
getargs-derive = "0.1"
getargs = "0.5"

No feature is enabled by default:

FeatureEnables
(none)Everything not listed below, in no_std without an allocator. Repeated values are stored in Values<T, N>.
heaplessheapless::Vec<T, N> fields for repeated values, stored inline without allocation.
allocVec<T> fields for repeated values.
stdEnvironment variable fallbacks from the process environment, shell completions and man pages, OsStr/Path/PathBuf fields and from_args_os. Implies alloc.

For a regular command-line application, enable std:

cargo add getargs-derive --features std

§Quick Start

use getargs_derive::{GetArgs, ValueEnum};

#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
enum Format {
    Json,
    Yaml,
    Toml,
}

/// Convert configuration files between formats.
#[derive(Debug, GetArgs)]
#[command(name = "confconv", version = "1.0.0")]
struct Cli<'a> {
    /// File to convert.
    input: &'a str,
    /// Output format.
    #[arg(short, long, value_enum, default_value_t = Format::Toml)]
    format: Format,
    /// Write the result to this file instead of standard output.
    #[arg(short, long)]
    output: Option<&'a str>,
    /// Print more details, repeat for even more.
    #[arg(short, long, action = Count)]
    verbose: u8,
}

fn main() {
    let args: Vec<String> = std::env::args().skip(1).collect();
    let cli = match Cli::from_args(args.iter().map(String::as_str)) {
        Ok(cli) => cli,
        Err(error) if error.is_help() || error.is_version() => {
            println!("{error}");
            std::process::exit(0);
        }
        Err(error) => {
            eprintln!("error: {error}");
            std::process::exit(2);
        }
    };
    println!("{cli:?}");
}

confconv --help prints the help generated at compile time, the Cli::HELP constant:

Convert configuration files between formats

Usage: confconv [OPTIONS] <INPUT>

Arguments:
  <INPUT>  File to convert

Options:
  -f, --format <FORMAT>  Output format [default: toml] [possible values: json, yaml, toml]
  -o, --output <OUTPUT>  Write the result to this file instead of standard output
  -v, --verbose...       Print more details, repeat for even more
  -h, --help             Print help
  -V, --version          Print version

and a typo gets a suggestion:

$ confconv config.json --frmat yaml
error: unexpected argument '--frmat' found

  tip: a similar argument exists: '--format'

The parser never prints or exits by itself: from_args takes any iterator of &str and returns the struct or an Error, so the same code works in tests, in no_std firmware reading arguments from a serial console, or behind parse when you already have a getargs::Options. With the std feature, Cli::from_args_os() reads std::env::args_os() directly and accepts non-UTF-8 arguments.

use getargs_derive::GetArgs;

#[derive(GetArgs)]
struct Cli<'a> {
    input: &'a str,
    #[arg(short, long)]
    verbose: bool,
    #[arg(short, long, default_value = "output.txt")]
    output: &'a str,
}

let cli = Cli::from_args(["input.txt", "--verbose"].into_iter()).unwrap();
assert_eq!(cli.input, "input.txt");
assert!(cli.verbose);
assert_eq!(cli.output, "output.txt");

§Compared to Clap

getargs-derive implements a Clap-inspired subset of Clap’s derive API for programs where Clap does not fit, such as no_std targets. It is not a drop-in replacement: Clap Compatibility lists what is shared and what is not supported.

getargs-deriveClap
no_std, no allocatoryesno, requires std
Help text&'static str built at compile timebuilt at run time
Derive API, doc comments as helpyesyes
Builder APInoyes
Subcommands, flatten, ValueEnumyesyes
Defaults, env fallbacks, aliases, Count flagsyesyes
Relationsconflicts_with, requires, required_unless_present, groupsmany more variants
Value validationparser functions, integer ranges, possible_valuesvalue_parser! and custom parsers
“Did you mean” suggestionsyesyes
Non-UTF-8 argumentsyesyes
Shell completionsbash, zsh, fish (std)more shells, dynamic completion
Man pagesyes (std)with clap_mangen
Colored output, terminal-width wrappingnoyes
Prints help and exitsno, your code decidesyes, by default

Unsupported Clap attributes are rejected at compile time rather than silently ignored.

§Guide

  • Attribute Reference: #[arg(...)] and #[command(...)] attributes, argument resolution and supported field types.
  • Flag Actions: SetTrue, SetFalse and Count flags.
  • Argument Aliases: hidden and visible long and short aliases.
  • Value Enums: #[derive(ValueEnum)] and #[arg(value_enum)] for arguments accepting a fixed set of values.
  • Default Values: default_value and default_value_t.
  • Environment Variables: env fallbacks, parse_with_env and the std feature.
  • Positional and Optional Arguments: positional arguments and Option<T> fields.
  • Repeated Values: repeated options, value_delimiter, positionals collecting the remaining arguments with num_args, and the Values, heapless::Vec and Vec storage options.
  • Argument Relations: conflicts_with, requires, required_unless_present and argument groups.
  • Value Validation: value_parser functions and ranges, and possible_values.
  • Parsing Modes: values starting with -, negative numbers and last positionals, and the limits imposed by getargs.
  • Flattened Structs: #[command(flatten)] to reuse the arguments of another struct.
  • Subcommands: #[derive(Subcommand)], #[command(subcommand)] fields, nested subcommands and global arguments.
  • Generated Help: the HELP and LONG_HELP constants, -h/--help, disable_help_flag, and help customization (hidden arguments, headings, ordering, extra text and wrapping).
  • Version Flag: #[command(version)], -V/--version and the VERSION/VERSION_TEXT constants.
  • Error Handling: the Error enum, its Clap-style messages and “did you mean” suggestions.
  • Shell Completions and Man Pages: the Command metadata trait, and bash, zsh and fish completion scripts and man pages with the std feature.
  • Non-UTF-8 Arguments: from_bytes and parse_bytes for raw &[u8] arguments, &[u8], &OsStr and PathBuf fields, and from_args_os with the std feature.
  • Clap Compatibility: what is shared with Clap, and what is not supported.
  • no_std Support: allocation-free parsing and the crate features.

Every guide page lists the compile-time diagnostics related to its topic.

§Minimum Supported Rust Version

getargs-derive requires Rust 1.88 or newer, and is tested against it in CI.

§License

Licensed under the MIT License.


Developed by Alix ANNERAUD.

Modules§

completionsstd
Shell completion scripts and man pages generated from the Command metadata.
guide
User guide for getargs-derive, one page per topic.

Structs§

ArgInfo
The description of one argument.
CommandInfo
The description of a command: its name, texts, arguments and subcommands.
Lossy
Displays bytes that may not be valid UTF-8, without allocating.
ParseValueEnumError
The error returned by the FromStr implementation generated by #[derive(ValueEnum)] when a string matches no variant.
Values
A vector of at most N values stored inline, without allocation.

Enums§

ArgKind
How an argument is given on the command line.
Error
Errors that can occur when parsing CLI arguments with GetArgs.
Opt
An option as it was written on the command line, without its leading dashes.

Traits§

Command
Compile-time description of a command line interface, implemented by #[derive(GetArgs)].
ValueEnum
An enum whose variants are the accepted values of an argument.

Derive Macros§

GetArgs
Derive macro for the getargs crate.
Subcommand
Derive macro for an enum of subcommands, used by a #[command(subcommand)] field of a struct deriving GetArgs.
ValueEnum
Derive macro implementing getargs_derive::ValueEnum and FromStr for an enum with unit variants.