Add gumdrop to your project
masterTo use gumdrop in your Rust project, add it as a dependency in your Cargo.toml file. This provides an option parser with custom derive support.
[dependencies]
gumdrop = "0.8"repository·master·Indexed 42 days ago
https://github.com/murarth/gumdropA Rust option parser providing custom derive support for defining command-line interfaces. It allows developers to use the #[derive(Options)] procedural macro on structs and enums to automatically generate argument parsers, supporting subcommands, positional arguments, and customizable flags for short/long options, default values, and custom parsing functions. Version 0.8.1.
To use gumdrop in your Rust project, add it as a dependency in your Cargo.toml file. This provides an option parser with custom derive support.
[dependencies]
gumdrop = "0.8"In addition to field attributes, certain flags can be set at the type level (on the struct or enum itself) to establish defaults for all contained fields:
no_help_flagno_longno_shortrequiredThe ParsingStyle enum controls how the parser treats "free" (non-option) arguments.
ParsingStyle::AllOptions: The default. The parser continues to look for options (like -o or --long) even after encountering free arguments.ParsingStyle::StopAtFirstFree: Once the first non-option argument is encountered, all subsequent arguments are treated as free arguments, even if they look like options.use gumdrop::{Options, ParsingStyle};
#[derive(Debug, Options)]
struct MyOptions {
#[options(help = "flag")]
flag: bool,
#[options(free)]
free: Vec<String>,
}
// If args are ["foo", "-flag"]
// AllOptions: flag=true, free=["foo", "-flag"]
// StopAtFirstFree: flag=false, free=["foo", "-flag"]The gumdrop_derive crate provides the #[derive(Options)] procedural macro. When applied to a struct or enum, it automatically generates an implementation of the gumdrop::Options trait, allowing you to parse command-line arguments into your data structures.
Variant(SubcommandOptions)).#[derive(gumdrop::Options)]
struct MyOptions {
#[options(help = "a help flag")]
help: bool,
}To create a subcommand-based CLI, use #[derive(Options)] on an enum.
struct must contain a field marked #[options(command)] that holds an Option<YourEnum>.enum should be a unary tuple variant containing a struct that implements Options.FooBar becomes foo-bar), but can be customized with #[options(name = "...")].Options defined in the top-level struct must appear before the subcommand name on the command line.
use gumdrop::Options;
#[derive(Debug, Options)]
struct MyOptions {
#[options(help = "be verbose")]
verbose: bool,
#[options(command)]
command: Option<Command>,
}
#[derive(Debug, Options)]
enum Command {
#[options(help = "make stuff")]
Make(MakeOpts),
#[options(help = "install stuff")]
Install(InstallOpts),
}
#[derive(Debug, Options)]
struct MakeOpts {
#[options(free)]
free: Vec<String>,
}
#[derive(Debug, Options)]
struct InstallOpts {
#[options(help = "target directory")]
dir: Option<String>,
}In gumdrop, you can define subcommands and their specific options using the #[options] attribute on a struct. This attribute can be used on the main configuration struct or on nested subcommand structs.
Supported attributes within #[options(...)] include:
name: Sets the name of the command.help: Sets the help text for the command.Additionally, you can use #[doc = "..."] to provide documentation that gumdrop will use for help generation.
Use the #[derive(Options)] macro on a struct to define command-line options. Each field in the struct represents an option or a free argument. Fields must have a Default implementation or an inline default value.
#[options(free)]: Marks a field (usually a Vec<String>) to collect all non-option arguments.#[options(help = "...")]: Provides a description for the help text.#[options(meta = "...")]: Specifies a placeholder name (e.g., N) for the argument in the usage text.#[options(count)]: Treats a boolean-like field as a counter (e.g., -vvv increments a u32 field).#[options(short = "?", long = "...")]: Overrides the automatically generated short and long flag names.#[options(no_short)] / #[options(no_long)]: Disables the short or long form of an option.#[options(parse(try_from_str = "func"))]: Uses a function that returns Result<T, E> for custom parsing.#[options(parse(from_str = "func"))]: Uses a function that always succeeds for custom transformation.use gumdrop::Options;
#[derive(Debug, Options)]
struct MyOptions {
#[options(help = "print help message")]
help: bool,
#[options(help = "give a string argument")]
string: Option<String>,
#[options(help = "give a number", meta = "N")]
number: Option<i32>,
#[options(help = "list of items")]
item: Vec<String>,
#[options(count, help = "increase counter")]
count: u32,
#[options(free)]
free: Vec<String>,
}
fn main() {
let opts = MyOptions::parse_args_default_or_exit();
println!("{:#?}", opts);
}Gumdrop provides helper functions to parse arguments directly from the process environment and handle errors or help requests automatically.
parse_args_default_or_exit(): The most common entry point. It uses the default ParsingStyle. If parsing fails, it prints the error to stderr and exits with code 2. If --help is requested, it prints usage and exits with code 0.parse_args_or_exit(style): Same as above, but allows specifying a ParsingStyle.use gumdrop::Options;
#[derive(Debug, Options)]
struct MyOptions {
#[options(help = "help")]
help: bool,
}
fn main() {
// Automatically handles --help and errors
let opts = MyOptions::parse_args_default_or_exit();
}The Options trait is the core interface for all CLI structures in gumdrop. It is typically implemented via #[derive(Options)].
parse<S: AsRef<str>>(parser: &mut Parser<S>) -> Result<Self, Error>: The low-level parsing logic.parse_args<S: AsRef<str>>(args: &[S], style: ParsingStyle) -> Result<Self, Error>: Parses a slice of arguments with a specific style.parse_args_default<S: AsRef<str>>(args: &[S]) -> Result<Self, Error>: Parses a slice of arguments using ParsingStyle::AllOptions.usage() -> &'static str: Returns the usage string for the type.self_usage() -> &'static str: Returns usage for the current instance (useful for subcommands).command_list() -> Option<&'static str>: Returns a list of available commands.command_name(&self) -> Option<&'static str>: Returns the name of the active command (for enums).You can apply global settings to your entire parser using the #[options(...)] attribute on your main struct. These settings affect how all subsequent options are treated:
no_help_flag: Disables the automatic --help flag.no_short: Disables short flags (e.g., -s) for all options.no_long: Disables long flags (e.g., --short) for all options.no_multi: Disables multi-value support (e.g., Vec<T>) for all options.required: Makes all options required by default.help = "...": Sets global help text.Example:
#[derive(Options)]
#[options(no_short, help = "My CLI Tool")]
struct MyOpts {
// ...
}You can control how struct fields are parsed by adding #[options(...)] attributes.
| Attribute | Description |
|---|---|
command | Marks the field as a subcommand. Must be Option<T> where T: Options (usually an enum). |
help_flag | Marks a bool field as a help flag. Fields named help get this automatically. |
no_help_flag | Prevents an option from being treated as a help flag. |
count | Increments the field each time the option appears (e.g., -vvv increments a u32). |
free | Marks a field as a positional argument. Non-option arguments fill these in sequence. The final free field can be a Vec<T> to collect all remaining arguments. |
short = "?" | Sets the short option character. |
no_short | Disables short option assignment for this field. |
long = "..." | Sets the long option name. |
no_long | Disables long option assignment for this field. |
default = "..." | Provides a default value (parsed like an argument). |
default_expr | Provides a default value as a Rust expression evaluated at compile time (requires default_expr feature). |
required | Causes an error if the option is missing (unless a help_flag is present). |
multi = "..." | Allows parsing an option multiple times using the specified method (e.g., push). Vec<T> fields are multi by default unless no_multi is used. |
no_multi | Inhibits automatic multi behavior for Vec<T> fields. |
not_required | Cancels a type-level required flag. |
help = "..." | Sets the help text. Can also use doc comments. |
meta = "..." | Sets the placeholder name shown in usage (e.g., --file <FILE>). |
parse(...) | Specifies a custom parsing function. Supported types: |
parse(from_str = "...") | fn(&str) -> T |
parse(try_from_str = "...") | fn(&str) -> Result<T, E> |
parse(from_str) | Uses From::from |
parse(try_from_str) | Uses FromStr::from_str |
You can control how a field's string argument is converted into its target type using parsing attributes:
from_str = "path": Uses the specified function to convert the string argument. If no path is provided (from_str), it uses ::std::convert::From::from.try_from_str = "path": Uses the specified function which returns a Result. If no path is provided (try_from_str), it defaults to ::std::str::FromStr::from_str.Example usage in an attribute:
#[options(from_str = "my_custom_parser")]
field: MyType,