1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
|
# 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.
|