flexiargs 2.0.0

A flexible, rule-based command dispatcher and argument parser with strict level control.
Documentation
  • Coverage
  • 100%
    29 out of 29 items documented1 out of 1 items with examples
  • Size
  • Source code size: 56.62 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 574.65 kB This is the summed size of all files generated by rustdoc for all configured targets
  • ร˜ build duration
  • this release: 2s Average build duration of successful builds.
  • all releases: 15s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Homepage
  • LinuxProativo/flexiargs
    1 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • LinuxProativo

๐Ÿ” Overview

flexiargs is a lightweight and dependency-friendly Rust crate designed for rule-based command-line argument parsing without relying on macros, derive systems, or bloated abstractions.

Instead of hiding behavior behind procedural magic, flexiargs provides a clean and explicit API that allows developers to bind CLI arguments directly to variables while retaining full control over parsing logic and application flow.

Built with simplicity and flexibility in mind, it gives you low-level control when you need it, without sacrificing ergonomics. With flexiargs, you can easily manage:

  • โš™๏ธ Parsing behavior and argument rules;

  • โœ… Validation and constraint handling;

  • ๐Ÿ“ฆ Unmatched or forwarded arguments;

  • ๐Ÿš€ Execution flow and command dispatching;

  • ๐Ÿงฉ Custom CLI architectures and dynamic behaviors;

Unlike heavy CLI frameworks, flexiargs focuses on predictable behavior, small footprint, and straightforward integration, making it ideal for projects where control and portability matter. Perfect for:

  • ๐Ÿ“ฆ Package managers;

  • ๐Ÿ› ๏ธ System utilities;

  • ๐Ÿ“ฅ Installers and bootstrap tools;

  • ๐Ÿงฉ Embedded CLI environments;

  • ๐Ÿš Custom shell-like applications;

  • ๐Ÿงช Internal developer tooling;

  • โšก Lightweight standalone binaries;

  • ๐Ÿš€ Experimental runtime environments;

โœจ Features

flexiargs is designed to keep CLI parsing simple, explicit, and predictable, without relying on macros or heavy abstractions. Instead of hiding behavior behind complex frameworks, it exposes clear rule-based control over how arguments are interpreted and processed.

  • ๐Ÿงฉ Simple rule-based parser API
    Defines parsing rules in a declarative way, without DSLs or code generation. You have full control over how each argument is interpreted.

  • ๐Ÿšซ No procedural macros
    No dependency on derive or procedural macros. This reduces compile time, avoids hidden behavior, and improves debugging clarity.

  • ๐Ÿ”  Supports short and long flags
    Full support for both short flags (-v, -h) and long flags (--verbose, --help) for flexible CLI design.

  • ๐Ÿ“ Supports argument formats

    • --flag=value
      Inline assignment for compact CLI usage.
    • --flag value
      Classic POSIX-style separation for readability in interactive usage.
  • ๐Ÿ”„ Typed parsing with FromStr
    Automatically converts string inputs into Rust types using the FromStr trait, ensuring type safety and reducing manual parsing code.

  • โš ๏ธ Automatic error formatting
    Parsing errors are automatically formatted in a clear and consistent way, improving end-user feedback.

  • ๐Ÿ“Œ Optional and required arguments
    Explicit support for required and optional parameters, removing the need for manual validation logic.

  • ๐Ÿ“š Multi-value collection
    Support for multiple values for the same flag (e.g. --file a b c), collected into typed containers.

  • ๐Ÿ“ฅ Positional argument passthrough
    Positional arguments can be captured or forwarded directly to subprocesses or higher-level handlers.

  • ๐Ÿ”’ Strict validation modes
    Enables strict parsing mode to reject unknown or malformed arguments, ideal for robust tools and system utilities.

  • ๐Ÿงต Thread-safe shared settings (RwLock)
    Safe shared state across threads using RwLock, useful for concurrent CLI applications or embedded runtimes.

  • โšก Custom actions/callbacks
    Allows execution of custom callbacks during parsing for dynamic or context-aware behavior.

  • ๐Ÿชถ Minimal and dependency-light design
    Keeps the core lightweight with minimal dependencies, focusing on portability and predictable behavior.

๐Ÿ“ฆ Installation

Add the crate to your Cargo.toml:

[dependencies]
flexiargs = "2.0"

๐ŸŒ Public API

The crate intentionally exposes a very small API surface:

pub use messages::{invalid_arg, missing_arg};
pub use help::ArgHelp;
pub use options::ParserOptions;
pub use flexiargs::{Arg, NULL_PTR, parse_into_vars};

๐Ÿšช Main Entry Points

Item Description
Arg Defines parsing rules
parse_into_vars Executes parsing with ParserOptions
ParserOptions Configuration for parsing behavior
invalid_arg Standardized invalid argument error
missing_arg Standardized missing parameter error

๐Ÿš€ Quick Example

use flexiargs::{Arg, parse_into_vars, ParserOptions};
use std::collections::VecDeque;

let mut sync_mode = false;
let mut packages = Vec::new();
let mut cache_dir = String::new();
let mut config_file: Option<String> = None;
let mut use_overlay = true;

let opts = ParserOptions {
subcommand: "aports",
..Default::default()
};

let mut rules = [
    Arg::bool(Some("-S"), "--sync", &mut sync_mode),
    Arg::collect_list(None, "--pkgs", "packages", &mut packages),
    Arg::value(None, "--cache-dir", "path", &mut cache_dir),
    Arg::option(Some("-c"), "--config", "file", &mut config_file),
    Arg::set(None, "--disable-overlay", false, &mut use_overlay),
];

let args = VecDeque::from(vec![
     "-S".to_string(),
    "wget".to_string(),
    "curl".to_string(),
    "--cache-dir=/tmp".to_string(),
    "--disable-overlay".to_string()
]);

parse_into_vars(&mut rules, args, opts).ok();
drop(rules);

println!("Sync: {}", sync_mode);
println!("Packages: {:?}", packages);
println!("Cache dir: {}", cache_dir);
println!("Overlay enabled: {}", use_overlay);

๐Ÿง  Core Concepts

๐Ÿ“ Parsing Rules

Every CLI behavior is defined using an Arg.

Each rule describes:

  • ๐Ÿท๏ธ Accepted flags;
  • โš™๏ธ Parsing behavior;
  • ๐ŸŽฏ Target variable;
  • โœ… Validation requirements;

Example:

Arg::bool(Some("-v"), "--verbose", &mut verbose)

๐Ÿงฑ Supported Rule Types

flexiargs is built around a small set of explicit rule types that define how command-line input is interpreted, validated, and transformed. Instead of relying on implicit behavior or hidden conventions, each rule type has a clear and predictable responsibility, allowing you to compose CLI behavior in a controlled and deterministic way.

๐Ÿšฉ Boolean Flags

Sets a boolean to true when matched.

let mut verbose = false;

Arg::bool(Some("-v"), "--verbose", &mut verbose);

โœ… Supports

  • -v
  • --verbose

๐Ÿ”ข Typed Values

Parses values using FromStr.

let mut port: u16 = 0;

Arg::value(
    Some("-p"),
    "--port",
    "port",
    &mut port
);

โœ… Supports

  • --port 8080
  • --port=8080
  • -p 8080

โ“ Optional Values

Stores values in Option<String>.

let mut config: Option<String> = None;

Arg::option(
    Some("-c"),
    "--config",
    "file",
    &mut config
);

๐Ÿ”ง Fixed State Assignment

Assigns a predefined value when matched.

let mut overlay = true;

Arg::set(
    None,
    "--disable-overlay",
    false,
    &mut overlay
);

๐Ÿ“š Multi-Value Collection

Collects sequential positional values until another flag appears.

let mut packages = Vec::new();

Arg::collect_list(
    None,
    "--pkgs",
    "packages",
    &mut packages
);

๐Ÿงช Example

--pkgs wget curl git

๐Ÿ“ค Result

["wget", "curl", "git"]

โšก Custom Actions

Executes arbitrary logic.

Arg::action(
    Some("-V"),
    "--version",
    || {
        println!("myapp 1.0");
    }
);

๐Ÿ’ก Useful for

  • ๐Ÿ“„ Version output
  • ๐Ÿ› ๏ธ Custom handlers
  • ๐Ÿšช Early exits
  • ๐Ÿ”„ Dynamic state manipulation

โ— Required Arguments

Arguments can be marked as essential:

Arg::value(
    None,
    "--root",
    "path",
    &mut root
).essential();

If no essential rule is matched:

myapp: setup: no essential parameter specified

๐Ÿงต Thread-Safe Global State

flexiargs includes built-in support for shared application state using RwLock.

๐Ÿšฉ Shared Boolean Flags

use std::sync::RwLock;

static DEBUG: RwLock<bool> = RwLock::new(false);

Arg::rw_bool(
    Some("-d"),
    "--debug",
    &DEBUG
);

๐Ÿ”ข Shared Typed Values

use std::sync::RwLock;

static PORT: RwLock<u16> = RwLock::new(8080);

Arg::rw_value(
    None,
    "--port",
    "port",
    &PORT
);

๐Ÿ”ง Shared Fixed Assignment

Arg::rw_set(
    None,
    "--production",
    true,
    &MODE
);

๐ŸŒ Environment Variables

flexiargs supports documentation and parsing of environment variables, allowing configuration via the environment.

Arg::env("ALPACK_ARCH", "Define the target architecture for rootfs"),

๐Ÿ” Parsing

Parsing in flexiargs is explicit, deterministic, and fully rule-driven. Each step of the parsing process is defined by clear rules that transform raw command-line input into structured, validated, and typed data.

๐Ÿ“ฅ Basic Parsing

let opts = ParserOptions {
subcommand: "server",
..Default::default()
};

parse_into_vars(&mut rules, args, opts).ok()?;

๐Ÿ“ฆ ParseResult

The parser returns a ParseResult. This structure provides a clean, streamlined interface for controlling your CLI's execution flow:

  • โœ… Result Handling: Encapsulates the success or failure of the parsing logic.
  • ๐Ÿ›Ÿ Automatic Help/Version: Handles --help, --version, and --help-all automatically, including output generation and exit state tracking.
  • ๐Ÿ”’ Execution Flow: Provides a fluent API to bridge the gap between parsing and your main application logic.

โœ… .help_or_err()

The primary method to control execution flow. It automatically handles help flags, returns errors if parsing failed, and indicates if the application should exit after showing help.

match parse_into_vars(&mut rules, args, opts).help_or_err() {
    Ok(true) => return Ok(()), // Help was shown, exit gracefully
    Ok(false) => { /* Continue execution */ }
    Err(e) => return Err(e),   // Parsing error occurred
}

๐Ÿ”“ .ok()

Extracts the raw parsing result, useful if you need to handle the Result<(), Box<dyn Error>> manually without the built-in help/error logic.

parse_into_vars(&mut rules, args, opts).ok()?;

๐Ÿ“ Positional Arguments

The parser supports -- to stop option parsing.

๐Ÿงช Example

myapp --verbose -- file1 file2

Everything after -- becomes positional data.

โš ๏ธ Error Messages

flexiargs provides standardized and human-readable errors automatically.

โŒ Invalid arguments

myapp: invalid argument '--unknown'
Use 'myapp --help' to see available options.

โŒ Missing values

myapp: setup: --port requires a <port>.
Usage: myapp setup --port <port>

๐ŸŽฏ Argument Matching

Rules in flexiargs define how input tokens are interpreted and matched against declared CLI arguments. This matching system is flexible but explicit, allowing multiple naming styles and aliasing strategies while keeping behavior predictable and rule-based. Rules support:

  • ๐Ÿ”ค Short flags;
  • ๐Ÿท๏ธ Long flags;
  • ๐Ÿ”€ Aliases via |;
  • ๐Ÿงท Inline assignment;

๐Ÿงช Example

Arg::bool(
    Some("-v"),
    "--verbose|--debug",
    &mut verbose
);

โœ… Support

  • -v
  • --verbose
  • --debug

Argument matching in flexiargs is designed to be both flexible and explicit. Instead of enforcing a single naming convention, it allows multiple identifiers and aliases per argument while keeping resolution deterministic and rule-based.

โš™๏ธ ParserOptions

ParserOptions is the central configuration structure for flexiargs. It replaces direct function parameters with a robust, extensible configuration object, allowing you to fine-tune parsing behavior, validation rules, and context.

๐Ÿ“ Definition

pub struct ParserOptions<'a> {
    /// The name of the subcommand being parsed, used for error messages.
    pub subcommand: &'a str,
    /// If true, unknown arguments will trigger an error.
    pub strict: bool,
    /// Rejects unmatched arguments up to a specific depth (if Some).
    pub strict_level: Option<usize>,
    /// If true, ignores help/version flags and treats them as standard arguments.
    pub ignore_help: bool,
    /// If true, suppresses parsing errors, allowing unmatched args to pass through.
    pub passthrough: bool,
    /// Fails the parsing process if no arguments were supplied.
    pub require_args: bool,
    /// A mutable reference to collect unmatched positional arguments.
    pub collect_args: Option<&'a mut VecDeque<String>>,
    /// A list of help rules for automated documentation.
    pub help_rules: &'a [ArgHelp<'a>],
}

๐Ÿ’ก Why use ParserOptions?

  • Centralized Control: Configure all parsing aspects (strictness, collection, requirements) in one place before invoking parse_into_vars.
  • Cleaner API: Keeps the parse_into_vars signature stable even as you add new features.
  • Fluent Setup: Easily derive from Default and override only the fields you need.

๐Ÿš€ Usage Example

let mut remaining = VecDeque::new();

let opts = ParserOptions {
    subcommand: "profile",
    strict: true,
    require_args: true,
    collect_args: Some(&mut remaining),
    ..Default::default()
};

parse_into_vars(&mut rules, args, opts).help_or_err()?;

๐Ÿค– AutoHelp System

flexiargs provides an automated help generation system that maps your defined rules and metadata into a structured, readable documentation output. Instead of maintaining a separate manual, you define the application properties and command context directly in your code.

๐Ÿ“ฆ App Properties

Defines the core metadata for the application, such as name, version, and a brief description.

ArgHelp::properties(
    "ALPack", 
    "A flexible package manager utility", 
    "1.2.0"
);

๐Ÿ› ๏ธ Subcommand Definition

Documents a subcommand. Use this to organize complex CLI tools into logical groups.

ArgHelp::subcommand(
    None,
    "profile",
    "Manage system profiles"
);

๐Ÿ“„ Argument Documentation

Documents a specific argument. You can add metadata strings (like <DIR>) to improve clarity.

ArgHelp::arg(
    Some("-r"),
    "--rootfs",
    "Specify rootfs directory"
)
.meta("<DIR>");

๐ŸŒ Environment Variable Documentation

Documents environment variables that influence the application behavior, ensuring they appear in the generated help output.

ArgHelp::env(
    "ALPACK_ARCH",
    "Define the target architecture for rootfs"
);

๐Ÿ“ Contextual Grouping

Limits the visibility of an argument to specific subcommands. This is essential when generating full help outputs with --help-all.

ArgHelp::arg(
    Some("-c"),
    "--config",
    "Path to config file"
)
.context(&["profile", "setup"]);

๐Ÿค Contributing

Contributions, improvements, and issue reports are welcome.

๐Ÿšง Possible Future Extensions

  • ๐Ÿš Shell completion generation

๐Ÿ“œ MIT License

This repository has scripts created to be free software.
Therefore, they can be distributed and/or modified within the terms of the MIT License.

See the MIT License file for details.

๐Ÿ“ฌ Contact & Support