Skip to content

A lightweight library for parsing command-line arguments in Rust with no external dependencies.

Notifications You must be signed in to change notification settings

voidember/micro_args

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

micro_args

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.

Features

  • 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.
  • User Friendly: Automatic generation of help (--help) and version information (--version). Suggestions for typos in arguments ("Did you mean...?").

Installation

Add the dependency to your Cargo.toml:

[dependencies]
micro_args = "0.1.0"

Quick Start

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);
    }
}

Detailed Guide

1. Creating an Application

The main entry point is the App struct.

let app = App::new("myprog")
    .version("0.1.0")
    .author("John Doe")
    .about("Program description");

2. Defining Arguments

Arguments are created using the Arg struct and added to the application using the .arg() method.

Flags

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)

Options

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 value

Positional Arguments

Arguments without flags, defined by their order.

Arg::new("files")
    .help("List of files to process")
    .multiple(true) // Accepts multiple values

3. Getting Parsing Results

The 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);

4. Subcommands

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"),
}

5. Validation

micro_args provides tools to ensure correct input.

Conflicts and Dependencies

Arg::new("output")
    .conflicts_with("stdout") // Cannot use --output with --stdout
    .requires("format")       // If --output is used, --format must also be used

Possible Values

Arg::new("mode")
    .possible_values(&["fast", "slow", "extreme"])

Custom Validators

Arg::new("age")
    .validator(|v| {
        if v.parse::<u8>().is_ok() {
            Ok(())
        } else {
            Err(String::from("Age must be a number"))
        }
    })

Path Validation

use micro_args::PathValidator;

Arg::new("config")
    .validator_path(PathValidator::MustExist)

Error Handling

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
    }
}

License

This project is licensed under the MIT License.

About

A lightweight library for parsing command-line arguments in Rust with no external dependencies.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages