9 个版本 (重大更改)

0.13.1 2024 年 8 月 12 日
0.12.4 2024 年 7 月 30 日
0.11.5 2023 年 11 月 25 日
0.10.0 2023 年 7 月 22 日
0.3.6 2021 年 11 月 25 日

#79命令行界面

Download history 151/week @ 2024-05-06 12/week @ 2024-05-20 9/week @ 2024-06-03 7/week @ 2024-06-10 149/week @ 2024-06-24 26/week @ 2024-07-01 434/week @ 2024-07-29 124/week @ 2024-08-05 141/week @ 2024-08-12

每月下载量 699
用于 3 个crate(直接使用2个)

MPL-2.0 许可证

585KB
15K SLoC

aopt

为 Rust 提供一个灵活且类型化的类似 getopt 的命令行框架。

功能

  • 选项支持

    • 支持前缀选项,例如 -f--flag/flag

    • 支持选项值,例如 -f 42--flag=3.14/flag=foo

    • 支持多种风格的选项,例如 -f 42-f=42/f42

    • 支持组合风格的选项,例如 -abc-a-b-c 相同。

    • 支持位置参数,请参阅 Index

    • 支持特殊选项和标志,请参阅 StopStdin

    • 支持类型支持,您可以在解析时验证选项的值。

    查看内置的选项类型 AOpt

  • 支持非 UTF-8 参数。

  • 支持回调支持。

    可以设置在解析期间被调用的回调,请参阅 ParserInvoker

  • 支持值支持。

    默认情况下,aopt 将保存原始值和解析值到 ValStorer

  • 支持策略支持。

    • DelayPolicy 在解析任何其他选项之前处理位置参数。

    • FwdPolicy 在位置参数之前处理选项。

    • PrePolicy 可以帮助您部分处理选项。

  • 派生支持

    • 查看 cote 库以获取派生支持和帮助信息生成。

设置

cargo添加aopt

sync 功能

如果您希望当前库的工具实现 SendSync,您可以启用 sync 功能。

简单的流程图

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

示例

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 输出
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)
  • 使用 getopt! 解析多个子命令。
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 输出

    调用列表命令:debug=true, force=false, local-only=false, source="lib.rs"

  • app.exe update -force -source=crates.io 输出

    调用更新命令:debug=false, force=true, source="crates.io"

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

    调用安装命令:debug=false, override=true, source=AStr("crates.io")

  • app.exe in aopt 输出

    错误:命令不匹配

更多

  • simple-find-file

一个简单的文件搜索工具,尝试使用 cargo install --path simple-find-file

  • snowball-follow

获取 xueqiu.com 中股票的关注数,尝试使用 cargo install --path snowball-follow

  • 指数成分

搜索并列出指数成分,尝试使用 cargo install --path index-constituent

发布日志

查看 链接

许可

MPL-2.0

依赖

~1–1.4MB
~26K SLoC