Argument parsing for the future 🚀

Overview

argi

Argument parsing for the future 🚀

Features

  • Macro-based approach, providing an intuitive way to layout a cli
  • Rich auto-help generation, styling based off of python's click library
  • Zero dependencies
  • Speedy compile times
  • Low binary bloat

This library is intended to be a replacement for both heavier structopt/clap-based interfaces due to amount of features contained within, as well as slim ones based upon pico-args due to the small workflow and compilation footprint. As this crate isn't fully battle-tested yet, smaller programs are a prime contender for usage with this library.

Usage

Place the following into your Cargo.toml file:

[dependencies]
argi = "0.1.0-beta.5"

Example

Complete demo (help page):

use argi::{cli, data};

fn main() {
    cli!(
        help: "Imaginary webapp program, allowing simple tasks",
        launch: {
            help: "Launches instance to given address",
            run: (|ctx, _| todo!("Launch at port {:?}", data!(ctx => --port))),
            --db [url]: { help: "Database URL" },
            --bind [url]: { help: "Binding address" },
            --port [port]: { help: "Port to hook onto" },
        },
        delete [text?]: {
            help: "Performs the delete operation upon data",
            run: (|_, data| println!("Deleting {:?} item", data)),
            all: { help: "Deletes everything" }
        }
    )
    .launch();
}

You can find more of the examples shown below within the useful examples/ directory!

Licensing

This project is dual-licensed under both MIT and Apache, so feel free to use either at your discretion. Links to the files are listed below:

Comments
  • Common arg/command

    Common arg/command

    There are many reused sections to both commands and args, see:

    pub struct Argument<'a> {
        /// Calls which can be made which instigate this argument
        pub instigators: &'a [&'a str],
        // the following values have been flattened into this and argument and function the same, this is for end user ease of use as the cost of us
        /// Help message, if added, for this argument
        pub help: Help<'a>,
        /// The type of data this argument parses, if any
        pub parses: Option<&'a str>,
        /// Indicates if a user has invoked this argument at any point
        pub used: bool,
        /// User-implemented closure which is ran at parse-time, if added
        pub run: Option<fn(&Self, Option<String>)>,
        /// Raw data found from parsing
        pub data: Option<String>,
    }
    

    versus the command:

    pub struct Command<'a> {
        pub name: &'a str,
        pub args: Vec<Argument<'a>>,
        pub subcmds: Vec<Command<'a>>,
        // the following values have been flattened into this and argument and function the same, this is for end user ease of use as the cost of us
        /// Help message, if added, for this argument
        pub help: Help<'a>,
        /// The type of data this command parses, if any
        pub parses: Option<&'a str>,
        /// Indicates if a user has invoked this command at any point
        pub used: bool,
        /// User-implemented closure which is ran at parse-time, if added
        pub run: Option<fn(&Self, Option<String>)>,
        /// Raw data found from parsing
        pub data: Option<String>,
    }
    

    Only 4 items in total are different (1 for arguments, 3 for commands) and the rest are flattened badly for better user experience, which is now null and void due to the inclusion of the data() command method.

    enhancement large feature 
    opened by Owez 4
  • Example in README is defective

    Example in README is defective

    Need to change the cli! curly braces to parens (or otherwise surround the cli! invocation with parens to make an expression) for the README example to compile.

    Once compiled, the README example produces no output when run.

    opened by BartMassey 1
  • Optional data

    Optional data

    The macro should allow [value?] for optional data along with optional: true for long-form inputting. Should then not give data required errors or no commands inputted

    enhancement 
    opened by Owez 1
  • Improved `.data()` fetching

    Improved `.data()` fetching

    A further extension to .data() fetching should be multiple parts in data like so:

    ctx.data("subcmd --argument")
    

    Instead of the current system which is:

    ctx.get_cmd("subcmd").data("--argument")
    

    Originally posted by @Owez in https://github.com/Owez/argi/issues/10#issuecomment-940801429

    opened by Owez 1
  • Replace `HelpType` with just an `Option<&str>` type

    Replace `HelpType` with just an `Option<&str>` type

    Simpler and less prone to weirdness caused by a user potentially submitting "path" instead of path etc; simplifying checks and the library as a whole. The None still acts as a barrier so nothing really changes on that front

    enhancement 
    opened by Owez 1
  • Less janky code for string writes

    Less janky code for string writes

    https://github.com/Owez/clonk/blob/15e8676fe218f63a4f6ca36f4f33300161f9c2d3/src/lib.rs#L293

    Self-explanatory once you read the rest of it; the current .push_str() and format!() system isn't the best and should be replaced by a write!() macro.

    The reason why the function itself returns String is to simplify the logistics of getting it's length compared to writing directly to the buffer, due to how the tab_to function works to format help (currently, see #2).

    bug enhancement 
    opened by Owez 1
  • Allow short arguments to have multiple characters

    Allow short arguments to have multiple characters

    https://github.com/Owez/clonk/blob/15e8676fe218f63a4f6ca36f4f33300161f9c2d3/src/lib.rs#L145

    Arguments formatted as -a are currently allowed but not ones like -ab (which go to both -a and -b) when inputted by a user.

    EDIT: the overall issue is still relevant despite the codeblock shown being outdated.

    enhancement good first issue 
    opened by Owez 1
  • Clean up `cli!()` and `cli_below!()` macros

    Clean up `cli!()` and `cli_below!()` macros

    They currently have a mixture of brute-force matching and TT munching, where we should really only be using TT munching under the current design which is superior. Another speedup would be moving away from the non-functionised part in cli_below!() which is as so:

    // recursion-only
    ($cmd:expr; $($($left:literal),* $(,)? $(:)? { $($tail:tt)* }),* $(,)?) => {
        // etc
    }
    

    Doing this would most likely drastically help compiletimes for more complex cli apps, as well as allow easier maintenance.

    enhancement 
    opened by Owez 0
  • Optional commands shouldn't take precident over subcommands

    Optional commands shouldn't take precident over subcommands

    Optional arguments are currently gobbling up valid subcommands. For example, when a user tries ab cd and cd is a command but ab has optional data, optional takes precedence and gobbles when it shouldn't. This issue was taken from these two old and quite ambiguous comments:

    // TODO: optional is gobbling others, need to maybe peek and check
    // TODO: rewrite data
    
    bug 
    opened by Owez 0
  • Hyphenated arguments like `--long-opt` don't parse in macros

    Hyphenated arguments like `--long-opt` don't parse in macros

    If I try to use an argument with a hypen in it, I get a compile error like:

    error[E0609]: no field `args` on type `&argi::Argument<'_>`
      --> bin/main.rs:44:11
       |
    44 |     match data!(bool, ctx => --include-methods) {
       |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unknown field
    
    

    Is this supported? Could it be? Perhaps by specifying the arg in quotes/string...

    bug 
    opened by dan-da 1
  • Does it handle non-UTF8 filenames on Unix-like systems?

    Does it handle non-UTF8 filenames on Unix-like systems?

    Can it be used, for example, to pass entire command line array to a subprocess unmodified without restrictions, like xargs? Does it start from std::env::args (simpler, but makes this task impossible) or from std::env::args_os (proper way, but tricky)?

    enhancement large feature 
    opened by vi 2
  • Manpage auto-generation

    Manpage auto-generation

    Manual pages should also be a primary post-release feature, perhaps a little further down the line then #5 as they are still frequently used in modern times. It should not have any message truncation (#2) etc and should be in the man-page format.

    Not sure about if this should be a feature gate because the parsing complexity may be quite large due to specific manpage formatting requirements (i.e. the troff format).

    enhancement large feature 
    opened by Owez 0
  • "Did you mean .." typo correction

    Important post-release feature, having a typo correction algorithm implemented helps a lot in my opinion and its a feature I like to see on other argparsers but that's missing from this.

    enhancement large feature 
    opened by Owez 0
Owner
Owez
I'm Owen Griffiths, a developer and student currently residing in Liverpool, UK.
Owez
A full featured, fast Command Line Argument Parser for Rust

clap Command Line Argument Parser for Rust It is a simple-to-use, efficient, and full-featured library for parsing command line arguments and subcomma

null 10.4k Jan 10, 2023
Docopt for Rust (command line argument parser).

THIS CRATE IS UNMAINTAINED This crate is unlikely to see significant future evolution. The primary reason to choose this crate for a new project is if

null 743 Jan 1, 2023
A minimal argument parser

Pieces An argument parser built with control in mind. Parsing The results you get are dependent on what order you parse in. If you want to say only pa

ibx34 3 Sep 30, 2021
argmax is a library that allows Rust applications to avoid Argument list too long errors (E2BIG) by providing a std::process::Command wrapper with a

argmax argmax is a library that allows Rust applications to avoid Argument list too long errors (E2BIG) by providing a std::process::Command wrapper w

David Peter 22 Nov 20, 2022
A full featured, fast Command Line Argument Parser for Rust

clap Command Line Argument Parser for Rust It is a simple-to-use, efficient, and full-featured library for parsing command line arguments and subcomma

Ed Page 0 Jun 16, 2022
A simple, lightweight and extensible command line argument parser for rust codebases

A simple, lightweight and extensible command line argument parser for rust codebases. This crate aims to provide you with an easy-to-use and extensibl

Victor Ndaba 20 Nov 12, 2022
AniTUI is a CLI (and in the future a TUI) app for searching and wathching anime in MPV.

AniTUI is a CLI (and in the future a TUI) app for searching and wathching anime in MPV. This is a Rust rewrite (quite literally a rewrite) of Pystardu

null 7 Oct 31, 2022
A build system from the future 🖖

warp is an friendly, fast, correct, and extensible build system built for polyglot monorepos that uses JavaScript for its configuration and is built i

warp.build 7 Apr 4, 2023
Tree-sitter - An incremental parsing system for programming tools

tree-sitter Tree-sitter is a parser generator tool and an incremental parsing library. It can build a concrete syntax tree for a source file and effic

null 10.6k Jan 9, 2023
Application microframework with command-line option parsing, configuration, error handling, logging, and shell interactions

Abscissa is a microframework for building Rust applications (either CLI tools or network/web services), aiming to provide a large number of features w

iqlusion 524 Dec 26, 2022
This utility traverses through your filesystem looking for open-source dependencies that are seeking donations by parsing README.md and FUNDING.yml files

This utility traverses through your filesystem looking for open-source dependencies that are seeking donations by parsing README.md and FUNDING.yml files

Mufeed VH 38 Dec 30, 2022
Python PEP-440 Version Parsing

PyVer (WIP) Python PEP-440 Version Parsing This package allows for parsing Python PEP-440 version numbers and comparisons between PEP-440 Versions Usa

Allstreamer 3 Sep 18, 2022
Python PEP-440 Version Parsing

PyVer Python PEP-440 Version Parser This package allows for parsing Python PEP-440 version numbers and for comparisons between PEP-440 version numbers

null 3 Sep 18, 2022
Minecraft's command parsing library in Rust

brigadier-rs This crate is a parsing library for Minecraft commands inspired by Mojang's brigadier. It was developed for use with FalconMC but can be

FalconMC 2 Nov 13, 2022
Tool to allow parsing large JSON files without laoding into memory

Tool to allow parsing large JSON files without laoding into memory. Developed in Rust with adapters in other programming langauges for easy adoption

Salaah Amin 7 Jul 11, 2023
A Rust crate for parsing Windows user minidumps.

udmp-parser-rs: A Rust crate for parsing Windows user minidumps This is a cross-platform crate that parses Windows user minidump dumps that you can ge

Axel Souchet 14 Aug 16, 2023
A Rust crate for parsing HID Report Descriptors.

Project Mu HID Crate Repository This repository contains a library crate that provides parsing services for HID Report Descriptors. This repository is

Microsoft 3 Sep 25, 2023
Easy c̵̰͠r̵̛̠ö̴̪s̶̩̒s̵̭̀-t̶̲͝h̶̯̚r̵̺͐e̷̖̽ḁ̴̍d̶̖̔ ȓ̵͙ė̶͎ḟ̴͙e̸̖͛r̶̖͗ë̶̱́ṉ̵̒ĉ̷̥e̷͚̍ s̷̹͌h̷̲̉a̵̭͋r̷̫̊ḭ̵̊n̷̬͂g̵̦̃ f̶̻̊ơ̵̜ṟ̸̈́ R̵̞̋ù̵̺s̷̖̅ţ̸͗!̸̼͋

Rust S̵̓i̸̓n̵̉ I̴n̴f̶e̸r̵n̷a̴l mutability! Howdy, friendly Rust developer! Ever had a value get m̵̯̅ð̶͊v̴̮̾ê̴̼͘d away right under your nose just when

null 294 Dec 23, 2022
Rust derive-based argument parsing optimized for code size

Argh Argh is an opinionated Derive-based argument parser optimized for code size Derive-based argument parsing optimized for code size and conformance

Google 1.3k Dec 28, 2022
Low effort scraping Python's pickle format in Rust. It is to complete pickle parsing as BeautifulSoup was to complete HTML parsing.

repugnant-pickle Because it is, isn't it? This is a Rust crate for dealing with the Python pickle format. It also has support for opening PyTorch file

Kerfuffle 7 Apr 7, 2023