{"id":20309103,"url":"https://github.com/chaseruskin/cliproc","last_synced_at":"2026-01-08T04:45:46.068Z","repository":{"id":115332424,"uuid":"527803796","full_name":"chaseruskin/cliproc","owner":"chaseruskin","description":"A fast, low-level, and configurable command-line processor","archived":false,"fork":false,"pushed_at":"2024-07-25T05:38:50.000Z","size":126,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"trunk","last_synced_at":"2025-03-28T15:21:39.999Z","etag":null,"topics":["args","cli","parser","rust"],"latest_commit_sha":null,"homepage":"https://docs.rs/cliproc","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chaseruskin.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-08-23T02:27:04.000Z","updated_at":"2024-07-25T05:38:41.000Z","dependencies_parsed_at":null,"dependency_job_id":"f493475e-1913-4112-a586-fdc8b70c97fb","html_url":"https://github.com/chaseruskin/cliproc","commit_stats":null,"previous_names":["cdotrus/clif","cdotrus/cliproc","ujichase/cliproc","chaseruskin/cliproc"],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chaseruskin%2Fcliproc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chaseruskin%2Fcliproc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chaseruskin%2Fcliproc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chaseruskin%2Fcliproc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chaseruskin","download_url":"https://codeload.github.com/chaseruskin/cliproc/tar.gz/refs/heads/trunk","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246164448,"owners_count":20733806,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["args","cli","parser","rust"],"created_at":"2024-11-14T17:25:31.162Z","updated_at":"2026-01-08T04:45:46.016Z","avatar_url":"https://github.com/chaseruskin.png","language":"Rust","readme":"# `cliproc`\n\n[![Pipeline](https://github.com/chaseruskin/cliproc/actions/workflows/pipeline.yml/badge.svg?branch=trunk)](https://github.com/chaseruskin/cliproc/actions/workflows/pipeline.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Crates.io](https://img.shields.io/crates/v/cliproc.svg)](https://crates.io/crates/cliproc)\n\nThis library provides support for fast, low-level, and configurable command-line processing.\n\n``` toml\n[dependencies]\ncliproc = \"2.1.1\"\n```\n\n## Example\n\n``` rust\nuse cliproc::{cli, proc, stage::Memory};\nuse cliproc::{Arg, Cli, Command, ExitCode, Help};\nuse std::env;\n\n// 1. Define the struct and the data required to perform its task\nstruct Demo {\n    name: String,\n    count: Option\u003cu8\u003e,\n}\n\n// 2. Implement the `Command` trait to allow a struct to function as a command\nimpl Command for Demo {\n    // 2a. Map the command-line data to the struct's data\n    fn interpret(cli: \u0026mut Cli\u003cMemory\u003e) -\u003e cli::Result\u003cSelf\u003e {\n        cli.help(Help::with(HELP))?;\n        Ok(Demo {\n            name: cli.require(Arg::option(\"name\").switch('n'))?,\n            count: cli.get(Arg::option(\"count\").switch('c'))?,\n        })\n    }\n\n    // 2b. Process the struct's data to perform its task\n    fn execute(self) -\u003e proc::Result {\n        for _ in 0..self.count.unwrap_or(1) {\n            println!(\"Hello {}!\", self.name);\n        }\n        Ok(())\n    }\n}\n\n// 3. Build the command-line processor and run the command\nfn main() -\u003e ExitCode {\n    Cli::default().parse(env::args()).go::\u003cDemo\u003e()\n}\n\nconst HELP: \u0026str = \"\\\nA fast, low-level, and configurable command-line processor.\n\nUsage:\n    demo [options] --name \u003cname\u003e\n    \nOptions:\n    --name, -n \u003cname\u003e       Name of the person to greet              \n    --count, -c \u003ccount\u003e     Number of times to greet (default: 1)\n    --help, -h              Print this help information and exit\n\";\n```\n\nSee the [`examples/`](./examples/) folder for more demonstrations.\n\n## Details\n\nThe 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.\n\n1. _Build Stage_: The build stage provides methods to configure the command-line processor. This stage uses the builder pattern to set options.\n\n2. _Ready Stage_: The ready stage provides methods to determine how to run the command-line processor.\n\n3. _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.\n\n### Transitions\n\nParsing a set of arguments using `parse(...)` transitions the command-line processor from the build stage to the ready stage.\n\nAt the ready stage, the processor has two choices: _go_ or _save_:\n- `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.\n\n- `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.\n\n### Commands\n\nThe 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.\n\nAny struct can function as a command/subcommand as along as:\n1. Each field's type in the struct implements the standard library's [`std::str::FromStr`](https://doc.rust-lang.org/std/str/trait.FromStr.html) trait.\n2. The struct implements `cliproc`'s [`Command`](./src/proc.rs) (or [`Subcommand`](./src/proc.rs)) trait.\n\n### Arguments\n\nThere are 4 supported types of arguments recognized by `cliproc`:\n- _Flags_: boolean conditions (ex: `--verbose`)\n- _Options_: arbitrary types for values specified with as a key/value pair (ex: `--output \u003cfile\u003e`)\n- _Positionals_: arbitrary types for values specified based upon position in the argument list (ex: `\u003cname\u003e`)\n- _Subcommands_: arbitrary types for nesting commands that contain their own set of arguments (ex: `\u003ccommand\u003e`)\n\nThe 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.\n\nUpon interpreting a command or subcommand, the _argument discovery order_ must follow:\n1. Flags\n2. Options\n3. Positionals\n4. Subcommands\n\nFailure to specify the struct initialization in this order is a programmer's error and will result in a `panic!`.\n\n## Features\n\nThe command-line processor has the ability to:  \n\n- Accept long options for flags and options\n    - `--verbose`, `--output a.out`\n\n- Accept _switches_ (short options) for flags and options\n    - `-v`, `-o a.out`\n\n- Accept positional arguments\n    - `main.rs`\n\n- Nest commands within commands using subcommands\n    - `calc add 10 20`, `calc mult 3 9`\n\n- Accept attached value placement\n    - `--output=a.out`, `-o=a.out`\n\n- Aggregate switches\n    - `-v -f`, `-vf`\n\n- Capture variable instances of a flag with an optional maximum limit\n    - `--verbose --verbose --verbose`\n\n- Capture variable instances of an option (order-preserving) with an optional maximum limit\n    - `--num 2 --num 17 --num 5`\n\n- Capture variable positional calls for a single argument (order-preserving):\n    - `10 20 30`\n\n- Aggregate switches and assign a value to the final switch:\n    - `-vfo=a.out`\n\n- Prioritize flag for help information over any other parsing error\n\n- Enable/disable a help flag with custom text entry WYSIWYG\n\n- Retain parsing and argument handling knowledge to share arguments of a command with nested subcommands\n\n- Detect misspelled words using dynamic programming approach for sequence alignment algorithm with configurable threshold for similarity comparison\n\n- Verify there is no unused/unrecognized arguments before completing parsing\n\n- Preserve unprocessed arguments that follow an empty flag `--`","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchaseruskin%2Fcliproc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchaseruskin%2Fcliproc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchaseruskin%2Fcliproc/lists"}