Bug: 215313373

Clone this repo:
  1. 01802d5 Migrate 10 crates to monorepo am: edcbda3f38 by James Farrell · 1 year, 2 months ago main master
  2. edcbda3 Migrate 10 crates to monorepo by James Farrell · 1 year, 2 months ago main-16k
  3. aeaf4a6 Generate license header with cargo_embargo. am: 1c7c04c0f2 by Andrew Walbran · 1 year, 2 months ago
  4. 1c7c04c Generate license header with cargo_embargo. by Andrew Walbran · 1 year, 2 months ago
  5. e0fb861 Update Android.bp by running cargo_embargo am: 26dbec7f2e am: 35b5d79412 by James Farrell · 1 year, 5 months ago android15-tests-dev

Argh

Argh is an opinionated Derive-based argument parser optimized for code size

crates.io license docs.rs Argh

Derive-based argument parsing optimized for code size and conformance to the Fuchsia commandline tools specification

The public API of this library consists primarily of the FromArgs derive and the from_env function, which can be used to produce a top-level FromArgs type from the current program's commandline arguments.

Basic Example

use argh::FromArgs; #[derive(FromArgs)] /// Reach new heights. struct GoUp { /// whether or not to jump #[argh(switch, short = 'j')] jump: bool, /// how high to go #[argh(option)] height: usize, /// an optional nickname for the pilot #[argh(option)] pilot_nickname: Option<String>, } fn main() { let up: GoUp = argh::from_env(); } 

./some_bin --help will then output the following:

Usage: cmdname [-j] --height <height> [--pilot-nickname <pilot-nickname>] Reach new heights. Options: -j, --jump whether or not to jump --height how high to go --pilot-nickname an optional nickname for the pilot --help display usage information 

The resulting program can then be used in any of these ways:

  • ./some_bin --height 5
  • ./some_bin -j --height 5
  • ./some_bin --jump --height 5 --pilot-nickname Wes

Switches, like jump, are optional and will be set to true if provided.

Options, like height and pilot_nickname, can be either required, optional, or repeating, depending on whether they are contained in an Option or a Vec. Default values can be provided using the #[argh(default = "<your_code_here>")] attribute, and in this case an option is treated as optional.

use argh::FromArgs; fn default_height() -> usize { 5 } #[derive(FromArgs)] /// Reach new heights. struct GoUp { /// an optional nickname for the pilot #[argh(option)] pilot_nickname: Option<String>, /// an optional height #[argh(option, default = "default_height()")] height: usize, /// an optional direction which is "up" by default #[argh(option, default = "String::from(\"only up\")")] direction: String, } fn main() { let up: GoUp = argh::from_env(); } 

Custom option types can be deserialized so long as they implement the FromArgValue trait (automatically implemented for all FromStr types). If more customized parsing is required, you can supply a custom fn(&str) -> Result<T, String> using the from_str_fn attribute:

use argh::FromArgs; #[derive(FromArgs)] /// Goofy thing. struct FiveStruct { /// always five #[argh(option, from_str_fn(always_five))] five: usize, } fn always_five(_value: &str) -> Result<usize, String> { Ok(5) } 

Positional arguments can be declared using #[argh(positional)]. These arguments will be parsed in order of their declaration in the structure:

use argh::FromArgs; #[derive(FromArgs, PartialEq, Debug)] /// A command with positional arguments. struct WithPositional { #[argh(positional)] first: String, } 

The last positional argument may include a default, or be wrapped in Option or Vec to indicate an optional or repeating positional argument.

Subcommands are also supported. To use a subcommand, declare a separate FromArgs type for each subcommand as well as an enum that cases over each command:

use argh::FromArgs; #[derive(FromArgs, PartialEq, Debug)] /// Top-level command. struct TopLevel { #[argh(subcommand)] nested: MySubCommandEnum, } #[derive(FromArgs, PartialEq, Debug)] #[argh(subcommand)] enum MySubCommandEnum { One(SubCommandOne), Two(SubCommandTwo), } #[derive(FromArgs, PartialEq, Debug)] /// First subcommand. #[argh(subcommand, name = "one")] struct SubCommandOne { #[argh(option)] /// how many x x: usize, } #[derive(FromArgs, PartialEq, Debug)] /// Second subcommand. #[argh(subcommand, name = "two")] struct SubCommandTwo { #[argh(switch)] /// whether to fooey fooey: bool, } 

NOTE: This is not an officially supported Google product.

How to debug the expanded derive macro for argh

The argh::FromArgs derive macro can be debugged with the cargo-expand crate.

Expand the derive macro in examples/simple_example.rs

See argh/examples/simple_example.rs for the example struct we wish to expand.

First, install cargo-expand by running cargo install cargo-expand. Note this requires the nightly build of Rust.

Once installed, run cargo expand with in the argh package and you can see the expanded code.