Git Product home page Git Product logo

aopt's Introduction

aopt

A flexible and typed getopt like command line framwork for rust.

Features

  • Option support

    • Prefixed option support, such as -f, --flag, -flag or --/flag.

    • Option value support, such as -f 42, --flag 3.14 or --flag=foo.

    • Multiple style option support, such as -f 42, -f=42 or -f42.

    • Combing style support, such as -abc is same as -a -b -c.

    • Positional arguments support, see Index.

    • Special option - and -- support, see Stop and Stdin.

    • Type support, you can validator the value of option during parsing.

    See the built-in option type AOpt

  • Non UTF8 arguments support

  • Callback support

    Can set callback which will called during parsing, see Parser and Invoker.

  • Value support

    By default aopt will saving the raw value and parsed value in ValStorer.

  • Policy support

    • DelayPolicy process positional arguments before any other option.

    • FwdPolicy process options before positional arguments.

    • PrePolicy can help you process the options partial.

  • Derive support

    • Checkout cote crate for derive support and help message generate.

Setup

cargo add aopt

sync feature

If you want the utils of current crate implement Send and Sync, you can enable sync feature.

Simple flow chart

                     +---------------------------------------+
                     |             Policy                    |
                     |                                       |
+--------------+     |  +-----------+     +------------+     |                +-------------+
|              |     |  |           |     |            |     |   Invoke       |             |
|   Arguments  +---->|  |  Checker  |     |   Process  |<----+----------------+   Invoker   |
|              |     |  |           |     |            |     |   the callback |             |
+--------------+     |  +---^-------+     ++-----^-----+     |                +-------------+
                     |      |              |     |           |
                     |      |              |     |           |
                     +------+--------------+-----+-----------+
                            |              |     |
                            |              |     |
                            |  Save the values   |Process the arguments
                            |              |     |
                            |              |     |
                Check the options          |     |
                            |              |     |
                            |              |     |
                            |         +----v-----+-----------+
                            |         |                      |
                            +---------+      Option Set      |
                                      |                      |
                                      +----------------------+

Example

  • Using AFwdParser parsing process the command line.
use aopt::prelude::*;
use std::ops::Deref;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut parser = AFwdParser::default();

    parser.validator_mut().add_prefix("+");
    parser.add_opt("--depth=i")?.set_value_t(0i64); // int option
    parser.add_opt("-/r=b")?; // boolean flag
    parser
        .add_opt("--source=s!")? // ! means the option is force required
        .add_alias("+S")
        .on(
            |set: &mut ASet, _: &mut ASer, mut val: ctx::Value<String>| {
                let depth: &i64 = set["--depth"].val()?;
                println!("Adding location({}) with depth({})", val.deref(), depth);
                Ok(Some((val.take(), *depth)))
            },
        )?;
    parser.add_opt("destination=p!@-0")?.on(
        |_: &mut ASet, _: &mut ASer, mut val: ctx::Value<String>| {
            println!("Save destination location({})", val.deref());
            Ok(Some(val.take()))
        },
    )?;
    parser.add_opt("main=m")?.on(
        |set: &mut ASet, _: &mut ASer, mut val: ctx::Value<String>| {
            let src = set["--source"].vals::<(String, i64)>()?;
            let dest: &String = set["destination"].val()?;

            for (item, depth) in src {
                println!(
                    "Application {} will copy location({item}, depth={depth}) to destination({})",
                    val.deref(),
                    dest
                );
            }
            Ok(Some(val.take()))
        },
    )?;
    parser.parse_env()?.unwrap();

    Ok(())
}
  • app.exe --depth=98 +S github --depth=42 +S gitlab gitcode output
Adding location(github) with depth(98)
Adding location(gitlab) with depth(42)
Save destination location(gitcode)
Application target\debug\example.exe will copy location(github, depth=98) to destination(gitcode)
Application target\debug\example.exe will copy location(gitlab, depth=42) to destination(gitcode)
  • Using getopt! parsing multiple sub command.
use aopt::prelude::*;
use aopt::Error;
use std::ops::Deref;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut list = AFwdParser::default();
    let mut update = AFwdParser::default();
    let mut install = AFwdParser::default();

    list.add_opt("list=c")?;
    list.add_opt("ls=c")?;
    list.add_opt("-debug=b")?;
    list.add_opt("-force=b")?.add_alias("-f");
    list.add_opt("-local-only=b")?.add_alias("-l");
    list.add_opt("-source".infer::<String>())?
        .add_alias("-s")
        .set_value(String::from("lib.rs"));
    list.add_opt("main=m")?
        .fallback(|set: &mut ASet, _: &mut ASer| {
            println!(
                "invoke list command: debug={:?}, force={:?}, local-only={:?}, source={:?}",
                set["-debug"].val::<bool>()?,
                set["-force"].val::<bool>()?,
                set["-local-only"].val::<bool>()?,
                set["-source"].val::<String>()?,
            );
            Ok(None::<()>)
        })?;

    update.add_opt("update=c")?;
    update.add_opt("up=c")?;
    update.add_opt("-debug=b")?;
    update.add_opt("-force=b")?.add_alias("-f");
    update.add_opt("-source=s")?.add_alias("-s");
    update
        .add_opt("main=m")?
        .on(|set: &mut ASet, _: &mut ASer| {
            println!(
                "invoke update command: debug={:?}, force={:?}, source={:?}",
                set["-debug"].val::<bool>()?,
                set["-force"].val::<bool>()?,
                set["-source"].val::<String>()?,
            );
            Ok(Some(true))
        })?;

    install.add_opt("install=c")?;
    install.add_opt("in=c")?;
    install.add_opt("-debug=b")?;
    install.add_opt("-/override=b")?.add_alias("-/o");
    install.add_opt("-source=s")?.add_alias("-s");
    install.add_opt("name=p!@2")?.on(
        |set: &mut ASet, _: &mut ASer, mut val: ctx::Value<String>| {
            if val.deref() == "software" {
                println!(
                    "invoke install command: debug={:?}, override={:?}, source={:?}",
                    set["-debug"].val::<bool>()?,
                    set["-/override"].val::<bool>()?,
                    set["-source"].val::<String>()?,
                );
                Ok(Some(val.take()))
            } else {
                Err(aopt::raise_error!("command not matched"))
            }
        },
    )?;

    getopt!(Args::from_env(), &mut list, &mut update, &mut install)?;
    Ok(())
}
  • app.exe ls -debug output

    invoke list command: debug=true, force=false, local-only=false, source="lib.rs"

  • app.exe update -force -source=crates.io output

    invoke update command: debug=false, force=true, source="crates.io"

  • app.exe in software -/o -s crates.io output

    invoke install command: debug=false, override=true, source=AStr("crates.io")

  • app.exe in aopt output

    Error: command not matched

More

  • simple-find-file

A simple file search tools, try it using cargo install --path simple-find-file.

  • snowball-follow

Get the follow count of stock in xueqiu.com, try it using cargo install --path snowball-follow

  • index constituent

Search and list the constituent of index, try it using cargo install --path index-constituent

Release log

Follow the link.

LICENSE

MPL-2.0

aopt's People

Contributors

araraloren avatar

Stargazers

clia avatar  avatar

Watchers

James Cloos avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.