Crates.io | cliproc |
lib.rs | cliproc |
version | 2.1.1 |
source | src |
created_at | 2024-05-23 14:32:00.065592 |
updated_at | 2024-07-25 05:39:27.518398 |
description | A fast, low-level, and configurable command-line processor |
homepage | |
repository | https://github.com/chaseruskin/cliproc |
max_upload_size | |
id | 1249571 |
size | 157,413 |
cliproc
This library provides support for fast, low-level, and configurable command-line processing.
[dependencies]
cliproc = "2.1.1"
use cliproc::{cli, proc, stage::Memory};
use cliproc::{Arg, Cli, Command, ExitCode, Help};
use std::env;
// 1. Define the struct and the data required to perform its task
struct Demo {
name: String,
count: Option<u8>,
}
// 2. Implement the `Command` trait to allow a struct to function as a command
impl Command for Demo {
// 2a. Map the command-line data to the struct's data
fn interpret(cli: &mut Cli<Memory>) -> cli::Result<Self> {
cli.help(Help::with(HELP))?;
Ok(Demo {
name: cli.require(Arg::option("name").switch('n'))?,
count: cli.get(Arg::option("count").switch('c'))?,
})
}
// 2b. Process the struct's data to perform its task
fn execute(self) -> proc::Result {
for _ in 0..self.count.unwrap_or(1) {
println!("Hello {}!", self.name);
}
Ok(())
}
}
// 3. Build the command-line processor and run the command
fn main() -> ExitCode {
Cli::default().parse(env::args()).go::<Demo>()
}
const HELP: &str = "\
A fast, low-level, and configurable command-line processor.
Usage:
demo [options] --name <name>
Options:
--name, -n <name> Name of the person to greet
--count, -c <count> Number of times to greet (default: 1)
--help, -h Print this help information and exit
";
See the examples/
folder for more demonstrations.
The command-line processor is divided into 3 stages: build, ready, and memory. It is implemented using the typestate pattern to enforce valid state operations and state transitions at compile-time.
Build Stage: The build stage provides methods to configure the command-line processor. This stage uses the builder pattern to set options.
Ready Stage: The ready stage provides methods to determine how to run the command-line processor.
Memory Stage: The memory stage provides methods to handle requests for data that is available from the command-line. This stage is the final stage of the command-line processor.
Parsing a set of arguments using parse(...)
transitions the command-line processor from the build stage to the ready stage.
At the ready stage, the processor has two choices: go or save:
go()
runs the processor to completion by transitioning to the memory stage and then handling calling the specified struct as a command with its implementation of the Command
trait. This is the recommended choice for running the processor.
save()
puts off command interpretations and execution by only transitioning the processor to the memory stage. This allows the programmer to expliticly handle calling the specified struct as a command.
The raw vector of strings received from the command-line is processed by translating the strings into tokens to be interpreted by a struct implementing the Command
trait.
Any struct can function as a command/subcommand as along as:
std::str::FromStr
trait.cliproc
's Command
(or Subcommand
) trait.There are 4 supported types of arguments recognized by cliproc
:
--verbose
)--output <file>
)<name>
)<command>
)The command-line processor interprets arguments as they are provided. For this reason, there is a specific order in which a struct must handle its attributes according to which one of the argument types it requests data from.
Upon interpreting a command or subcommand, the argument discovery order must follow:
Failure to specify the struct initialization in this order is a programmer's error and will result in a panic!
.
The command-line processor has the ability to:
Accept long options for flags and options
--verbose
, --output a.out
Accept switches (short options) for flags and options
-v
, -o a.out
Accept positional arguments
main.rs
Nest commands within commands using subcommands
calc add 10 20
, calc mult 3 9
Accept attached value placement
--output=a.out
, -o=a.out
Aggregate switches
-v -f
, -vf
Capture variable instances of a flag with an optional maximum limit
--verbose --verbose --verbose
Capture variable instances of an option (order-preserving) with an optional maximum limit
--num 2 --num 17 --num 5
Capture variable positional calls for a single argument (order-preserving):
10 20 30
Aggregate switches and assign a value to the final switch:
-vfo=a.out
Prioritize flag for help information over any other parsing error
Enable/disable a help flag with custom text entry WYSIWYG
Retain parsing and argument handling knowledge to share arguments of a command with nested subcommands
Detect misspelled words using dynamic programming approach for sequence alignment algorithm with configurable threshold for similarity comparison
Verify there is no unused/unrecognized arguments before completing parsing
Preserve unprocessed arguments that follow an empty flag --