flexiargs 2.0.0

A flexible, rule-based command dispatcher and argument parser with strict level control.
Documentation
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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
<p align="center">
  <img src="https://raw.githubusercontent.com/LinuxProativo/flexiargs/refs/heads/master/logo.png" width="300"/>
</p>

<h1 align="center">FlexiArgs - Flexible Arguments Parser</h1>
<h3 align="center">โœจ Minimalist, Flexible, and Ergonomic CLI Parsing.</h3>

<p align="center">
    <img src="https://img.shields.io/badge/Platform-POSIX-FCC624?&logo=linux&style=flat-square"/>
    <img src="https://img.shields.io/github/actions/workflow/status/LinuxProativo/flexiargs/rust.yml?label=Test&style=flat-square&logo=github"/>
    <img src="https://img.shields.io/badge/RustC-1.85+-orange?style=flat-square&logo=rust"/>
    <img src="https://img.shields.io/github/languages/code-size/LinuxProativo/flexiargs?style=flat-square&logo=rust&label=Code%20Size"/>
</p>

## ๐Ÿ” 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`:

```toml
[dependencies]
flexiargs = "2.0"
```

## ๐ŸŒ Public API

The crate intentionally exposes a very small API surface:

```rust
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

```rust
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:

```rust
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.

```rust
let mut verbose = false;

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

### โœ… Supports

- `-v`
- `--verbose`

## ๐Ÿ”ข Typed Values

Parses values using `FromStr`.

```rust
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>`.

```rust
let mut config: Option<String> = None;

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

## ๐Ÿ”ง Fixed State Assignment

Assigns a predefined value when matched.

```rust
let mut overlay = true;

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

## ๐Ÿ“š Multi-Value Collection

Collects sequential positional values until another flag appears.

```rust
let mut packages = Vec::new();

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

### ๐Ÿงช Example

```bash
--pkgs wget curl git
```

### ๐Ÿ“ค Result

```rust
["wget", "curl", "git"]
```

## โšก Custom Actions

Executes arbitrary logic.

```rust
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:

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

If no essential rule is matched:

```text
myapp: setup: no essential parameter specified
```

## ๐Ÿงต Thread-Safe Global State

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

### ๐Ÿšฉ Shared Boolean Flags

```rust
use std::sync::RwLock;

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

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

### ๐Ÿ”ข Shared Typed Values

```rust
use std::sync::RwLock;

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

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

### ๐Ÿ”ง Shared Fixed Assignment

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

## ๐ŸŒ Environment Variables

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

```rust
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

```rust
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.

```rust
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.

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

## ๐Ÿ“ Positional Arguments

The parser supports `--` to stop option parsing.

### ๐Ÿงช Example

```bash
myapp --verbose -- file1 file2
```

Everything after `--` becomes positional data.

## โš ๏ธ Error Messages

flexiargs provides standardized and human-readable errors automatically.

### โŒ Invalid arguments

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

### โŒ Missing values

```text
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

```rust
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

```rust
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

```rust
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.

```rust
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.

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

### ๐Ÿ“„ Argument Documentation

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

```rust
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.


```rust
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`.

```rust
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]LICENSE file for details.

## ๐Ÿ“ฌ Contact & Support

* ๐Ÿ“ง **Email:** [m10ferrari1200@gmail.com]mailto:m10ferrari1200@gmail.com
* ๐Ÿ“ง **Email:** [contatolinuxdicaspro@gmail.com]mailto:contatolinuxdicaspro@gmail.com