1# Argh 2**Argh is an opinionated Derive-based argument parser optimized for code size** 3 4[](https://crates.io/crates/argh) 5[](https://github.com/google/argh/LICENSE) 6[](https://docs.rs/crate/argh/) 7 8 9Derive-based argument parsing optimized for code size and conformance 10to the Fuchsia commandline tools specification 11 12The public API of this library consists primarily of the `FromArgs` 13derive and the `from_env` function, which can be used to produce 14a top-level `FromArgs` type from the current program's commandline 15arguments. 16 17## Basic Example 18 19```rust,no_run 20use argh::FromArgs; 21 22#[derive(FromArgs)] 23/// Reach new heights. 24struct GoUp { 25 /// whether or not to jump 26 #[argh(switch, short = 'j')] 27 jump: bool, 28 29 /// how high to go 30 #[argh(option)] 31 height: usize, 32 33 /// an optional nickname for the pilot 34 #[argh(option)] 35 pilot_nickname: Option<String>, 36} 37 38fn main() { 39 let up: GoUp = argh::from_env(); 40} 41``` 42 43`./some_bin --help` will then output the following: 44 45``` 46Usage: cmdname [-j] --height <height> [--pilot-nickname <pilot-nickname>] 47 48Reach new heights. 49 50Options: 51 -j, --jump whether or not to jump 52 --height how high to go 53 --pilot-nickname an optional nickname for the pilot 54 --help display usage information 55``` 56 57The resulting program can then be used in any of these ways: 58- `./some_bin --height 5` 59- `./some_bin -j --height 5` 60- `./some_bin --jump --height 5 --pilot-nickname Wes` 61 62Switches, like `jump`, are optional and will be set to true if provided. 63 64Options, like `height` and `pilot_nickname`, can be either required, 65optional, or repeating, depending on whether they are contained in an 66`Option` or a `Vec`. Default values can be provided using the 67`#[argh(default = "<your_code_here>")]` attribute, and in this case an 68option is treated as optional. 69 70```rust 71use argh::FromArgs; 72 73fn default_height() -> usize { 74 5 75} 76 77#[derive(FromArgs)] 78/// Reach new heights. 79struct GoUp { 80 /// an optional nickname for the pilot 81 #[argh(option)] 82 pilot_nickname: Option<String>, 83 84 /// an optional height 85 #[argh(option, default = "default_height()")] 86 height: usize, 87 88 /// an optional direction which is "up" by default 89 #[argh(option, default = "String::from(\"only up\")")] 90 direction: String, 91} 92 93fn main() { 94 let up: GoUp = argh::from_env(); 95} 96``` 97 98Custom option types can be deserialized so long as they implement the 99`FromArgValue` trait (automatically implemented for all `FromStr` types). 100If more customized parsing is required, you can supply a custom 101`fn(&str) -> Result<T, String>` using the `from_str_fn` attribute: 102 103```rust 104use argh::FromArgs; 105 106#[derive(FromArgs)] 107/// Goofy thing. 108struct FiveStruct { 109 /// always five 110 #[argh(option, from_str_fn(always_five))] 111 five: usize, 112} 113 114fn always_five(_value: &str) -> Result<usize, String> { 115 Ok(5) 116} 117``` 118 119Positional arguments can be declared using `#[argh(positional)]`. 120These arguments will be parsed in order of their declaration in 121the structure: 122 123```rust 124use argh::FromArgs; 125 126#[derive(FromArgs, PartialEq, Debug)] 127/// A command with positional arguments. 128struct WithPositional { 129 #[argh(positional)] 130 first: String, 131} 132``` 133 134The last positional argument may include a default, or be wrapped in 135`Option` or `Vec` to indicate an optional or repeating positional argument. 136 137Subcommands are also supported. To use a subcommand, declare a separate 138`FromArgs` type for each subcommand as well as an enum that cases 139over each command: 140 141```rust 142use argh::FromArgs; 143 144#[derive(FromArgs, PartialEq, Debug)] 145/// Top-level command. 146struct TopLevel { 147 #[argh(subcommand)] 148 nested: MySubCommandEnum, 149} 150 151#[derive(FromArgs, PartialEq, Debug)] 152#[argh(subcommand)] 153enum MySubCommandEnum { 154 One(SubCommandOne), 155 Two(SubCommandTwo), 156} 157 158#[derive(FromArgs, PartialEq, Debug)] 159/// First subcommand. 160#[argh(subcommand, name = "one")] 161struct SubCommandOne { 162 #[argh(option)] 163 /// how many x 164 x: usize, 165} 166 167#[derive(FromArgs, PartialEq, Debug)] 168/// Second subcommand. 169#[argh(subcommand, name = "two")] 170struct SubCommandTwo { 171 #[argh(switch)] 172 /// whether to fooey 173 fooey: bool, 174} 175``` 176 177NOTE: This is not an officially supported Google product. 178 179 180## How to debug the expanded derive macro for `argh` 181 182The `argh::FromArgs` derive macro can be debugged with the [cargo-expand](https://crates.io/crates/cargo-expand) crate. 183 184### Expand the derive macro in `examples/simple_example.rs` 185 186See [argh/examples/simple_example.rs](./argh/examples/simple_example.rs) for the example struct we wish to expand. 187 188First, install `cargo-expand` by running `cargo install cargo-expand`. Note this requires the nightly build of Rust. 189 190Once installed, run `cargo expand` with in the `argh` package and you can see the expanded code. 191