# Argyle [![docs.rs](https://img.shields.io/docsrs/argyle.svg?style=flat-square&label=docs.rs)](https://docs.rs/argyle/) [![changelog](https://img.shields.io/crates/v/argyle.svg?style=flat-square&label=changelog&color=9b59b6)](https://github.com/Blobfolio/argyle/blob/master/CHANGELOG.md)
[![crates.io](https://img.shields.io/crates/v/argyle.svg?style=flat-square&label=crates.io)](https://crates.io/crates/argyle) [![ci](https://img.shields.io/github/actions/workflow/status/Blobfolio/argyle/ci.yaml?style=flat-square&label=ci)](https://github.com/Blobfolio/argyle/actions) [![deps.rs](https://deps.rs/repo/github/blobfolio/argyle/status.svg?style=flat-square&label=deps.rs)](https://deps.rs/repo/github/blobfolio/argyle)
[![license](https://img.shields.io/badge/license-wtfpl-ff1493?style=flat-square)](https://en.wikipedia.org/wiki/WTFPL) [![contributions welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square&label=contributions)](https://github.com/Blobfolio/argyle/issues) This crate provides a simple streaming CLI argument parser/iterator called `Argue`, offering a middle ground between the standard library's barebones `std::env::args_os` helper and full-service crates like [clap](https://crates.io/crates/clap). `Argue` performs some basic normalization — it handles string conversion in a non-panicking way, recognizes shorthand value assignments like `-kval`, `-k=val`, `--key=val`, and handles end-of-command (`--`) arguments — and will help identify any special keys/values expected by your app. The subsequent validation and handling, however, are left _entirely up to you_. Loop, match, and proceed however you see fit. If that sounds terrible, just use [clap](https://crates.io/crates/clap) instead. Haha. ## Installation Add `argyle` to your `dependencies` in `Cargo.toml`, like: ``` [dependencies] argyle = "0.9.*" ``` ## Example A general setup might look something like the following. Refer to the documentation for `Argue`, `KeyWord`, and `Argument` for more information, caveats, etc. ```rust use argyle::{Argument, KeyWord}; use std::path::PathBuf; #[derive(Debug, Clone, Default)] /// # Configuration. struct Settings { threads: usize, verbose: bool, paths: Vec, } let args = argyle::args() .with_keywords([ KeyWord::key("-h").unwrap(), // Boolean flag (short). KeyWord::key("--help").unwrap(), // Boolean flag (long). KeyWord::key_with_value("-j").unwrap(), // Expects a value. KeyWord::key_with_value("--threads").unwrap(), ]); // Loop and handle! let mut settings = Settings::default(); for arg in args { match arg { // Help flag match. Argument::Key("-h" | "--help") => { println!("Help Screen Goes Here."); return; }, // Thread option match. Argument::KeyWithValue("-j" | "--threads", value) => { settings.threads = value.parse() .expect("Maximum threads must be a number!"); }, // Something else. Argument::Other(v) => { settings.paths.push(PathBuf::from(v)); }, // Also something else, but not String-able. PathBuf doesn't care // about UTF-8, though, so it might be fine! Argument::InvalidUtf8(v) => { settings.paths.push(PathBuf::from(v)); }, // Nothing else is relevant here. _ => {}, } } // Now that you're set up, do stuff… ```