A lightweight library for parsing command-line arguments in Rust with no external dependencies. It provides a simple and convenient Builder API for creating CLI applications.
- Zero Dependencies: The library has no external dependencies, ensuring fast compilation and small binary size.
- Simple API: Intuitive Builder API for configuring the application and arguments.
- Rich Functionality: Support for flags, options with values, and positional arguments.
- Subcommands: Support for nested commands (like
git clone,git commit, etc.). - Powerful Validation:
- Required arguments (
required). - Argument conflicts (
conflicts_with). - Argument dependencies (
requires). - Restricted possible values (
possible_values). - Custom value validators.
- Path existence checks.
- Required arguments (
- User Friendly: Automatic generation of help (
--help) and version information (--version). Suggestions for typos in arguments ("Did you mean...?").
Add the dependency to your Cargo.toml:
[dependencies]
micro_args = "0.1.0"Example of a simple application:
use micro_args::{App, Arg};
fn main() {
let matches = App::new("MyApp")
.version("1.0")
.author("Developer <dev@example.com>")
.about("Demo application")
.arg(Arg::new("config")
.short('c')
.long("config")
.help("Sets a custom config file")
.takes_value(true))
.arg(Arg::new("debug")
.short('d')
.help("Turn debugging information on"))
.arg(Arg::new("input")
.help("Input file")
.required(true)
.index(1)) // Positional argument
.get_matches();
// Gets a value for config if supplied by user
if let Some(config) = matches.value_of("config") {
println!("Value for config: {}", config);
}
// Check if the debug flag was used
if matches.is_present("debug") {
println!("Debugging is enabled");
}
// Gets the value of the positional argument
if let Some(input) = matches.value_of("input") {
println!("Processing file: {}", input);
}
}The main entry point is the App struct.
let app = App::new("myprog")
.version("0.1.0")
.author("John Doe")
.about("Program description");Arguments are created using the Arg struct and added to the application using the .arg() method.
Switch arguments that do not take values (e.g., --verbose or -v).
Arg::new("verbose")
.short('v')
.long("verbose")
.help("Increase logging verbosity")
.multiple(true) // Can be specified multiple times (-vvv)Arguments that require a value (e.g., --port 8080).
Arg::new("port")
.short('p')
.long("port")
.takes_value(true)
.help("Server port")
.default_value("8080") // Default valueArguments without flags, defined by their order.
Arg::new("files")
.help("List of files to process")
.multiple(true) // Accepts multiple valuesThe get_matches() method (or try_get_matches()) returns a Matches struct from which values can be extracted.
let matches = app.get_matches();
// Check if an argument is present
if matches.is_present("verbose") { ... }
// Number of occurrences (for flags)
let verbosity = matches.occurrences_of("verbose");
// Get string value
let port = matches.value_of("port").unwrap_or("80");
// Get typed value
let count: usize = matches.get_one("count").unwrap_or(0);You can create complex CLI interfaces with nested commands.
let app = App::new("git")
.subcommand(App::new("commit")
.about("Commit changes")
.arg(Arg::new("message").short('m').takes_value(true)))
.subcommand(App::new("clone")
.about("Clone a repository")
.arg(Arg::new("url").required(true)));
let matches = app.get_matches();
match matches.subcommand() {
Some(("commit", sub_matches)) => {
let msg = sub_matches.value_of("message").unwrap();
println!("Commit message: {}", msg);
},
Some(("clone", sub_matches)) => {
println!("Cloning {}", sub_matches.value_of("url").unwrap());
},
_ => println!("Use --help for more information"),
}micro_args provides tools to ensure correct input.
Arg::new("output")
.conflicts_with("stdout") // Cannot use --output with --stdout
.requires("format") // If --output is used, --format must also be usedArg::new("mode")
.possible_values(&["fast", "slow", "extreme"])Arg::new("age")
.validator(|v| {
if v.parse::<u8>().is_ok() {
Ok(())
} else {
Err(String::from("Age must be a number"))
}
})use micro_args::PathValidator;
Arg::new("config")
.validator_path(PathValidator::MustExist)If parsing fails, get_matches() automatically prints an error and exits the program. If you need manual control, use try_get_matches().
match app.try_get_matches() {
Ok(matches) => { /* ... */ },
Err(e) => {
eprintln!("Parsing error: {}", e);
// Handle error
}
}This project is licensed under the MIT License.