| # Argh |
| **Argh is an opinionated Derive-based argument parser optimized for code size** |
| |
| [](https://crates.io/crates/argh) |
| [](https://github.com/google/argh/LICENSE) |
| [](https://docs.rs/crate/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 |
| |
| ```rust,no_run |
| 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. |
| |
| ```rust |
| 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: |
| |
| ```rust |
| 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: |
| |
| ```rust |
| 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: |
| |
| ```rust |
| 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](https://crates.io/crates/cargo-expand) crate. |
| |
| ### Expand the derive macro in `examples/simple_example.rs` |
| |
| See [argh/examples/simple_example.rs](./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. |