22 个版本

0.3.5 2023 年 12 月 13 日
0.3.4 2023 年 7 月 26 日
0.3.2 2023 年 6 月 20 日
0.2.7 2022 年 11 月 15 日
0.1.1 2020 年 7 月 15 日

命令行界面 中排名 #47

Download history 4230/week @ 2024-04-08 3612/week @ 2024-04-15 4558/week @ 2024-04-22 4127/week @ 2024-04-29 4977/week @ 2024-05-06 4756/week @ 2024-05-13 4294/week @ 2024-05-20 4591/week @ 2024-05-27 5924/week @ 2024-06-03 5334/week @ 2024-06-10 5050/week @ 2024-06-17 4337/week @ 2024-06-24 4650/week @ 2024-07-01 5641/week @ 2024-07-08 3365/week @ 2024-07-15 4537/week @ 2024-07-22

18,475 次每月下载
15 个crate 中使用

MIT 许可证

85KB
1.5K SLoC

clio

clio 是一个用于解析 CLI 文件名的 Rust 库。

它实现了当文件名是 "" 时,将数据发送到 stdin/stdout 的标准 Unix 约定。通过 clap-parse 功能,它还增加了一些有用的过滤器来验证来自命令行参数的路径,例如检查路径是否存在或是否是目录。

用法

InputOutput 可以直接从 args_os 中的参数创建。如果由于任何原因无法打开文件,它们将返回错误。

// a cat replacement
fn main() -> clio::Result<()> {
    for arg in std::env::args_os().skip(1) {
        let mut input = clio::Input::new(&arg)?;
        std::io::copy(&mut input, &mut std::io::stdout())?;
    }
    Ok(())
}

如果您想延迟打开文件,可以使用 InputPathOutputPath。这可以避免在错误发生得非常早时留下空的输出文件。它们会在创建时检查路径是否存在、是否是文件,并且从理论上讲可以打开以获取更友好的错误信息。由于这可能会留下 TOCTTOU 错误,当真正打开文件时,如果某些东西已经改变,它们仍然会返回 Err

通过 clap-parse 功能,它们也被设计为与 clap 3.2+ 一起使用。

有关旧版 clap/structopt 的示例,请参阅 旧版文档

# #[cfg(feature="clap-parse")]{
use clap::Parser;
use clio::*;
use std::io::Write;

#[derive(Parser)]
#[clap(name = "cat")]
struct Opt {
    /// Input file, use '-' for stdin
    #[clap(value_parser, default_value="-")]
    input: Input,

    /// Output file '-' for stdout
    #[clap(long, short, value_parser, default_value="-")]
    output: Output,

    /// Directory to store log files in
    #[clap(long, short, value_parser = clap::value_parser!(ClioPath).exists().is_dir(), default_value = ".")]
    log_dir: ClioPath,
}

fn main() {
    let mut opt = Opt::parse();

    let mut log = opt.log_dir.join("cat.log").create().unwrap_or(Output::std_err());

    match std::io::copy(&mut opt.input, &mut opt.output) {
        Ok(len) => writeln!(log, "Copied {} bytes", len),
        Err(e) => writeln!(log, "Error {:?}", e),
    };
}
# }

其他 crate

无标题

Nameless 是 clap 的替代品,提供全服务的命令行解析。这意味着您只需编写一个带有您想要的类型的参数的主函数,添加一个常规文档注释,它就会使用过程宏的魔力来处理其余部分。

它的输入和输出流具有与 clio 相似的多项功能(例如,'-' 表示 stdin),但也支持透明地解压缩输入,以及更多远程选项,如 scp://

Patharg

如果您和我一样对在这个crate中为看似非常简单的任务编写的代码量感到震惊,那么 patharg 是一个更轻量级的crate,它通过 clap 处理 '-' 作为 stdin/stdout。

它不会在您要求之前打开文件或验证路径,从而避免了 TOCTTOU 问题,但在过程中会丢失漂亮的 clap 错误消息。

它还避免了处理查找和预先猜测输入是否支持查找的复杂性。

请注意,patharg 没有自定义 clap ValueParser,因此较旧的 clap 版本会通过 String 进行转换,因此路径需要是有效的 utf-8,而 Linux 和 Windows 都不能保证这一点。

或者

如果您只需要支持将 '-' 映射到 stdin(),请尝试从 patharg 提炼的这款可爱的函数。

它之所以能工作,是因为 either 在两边都实现了它们时,方便地添加了许多常见特性的 impl

    use either::Either;
    use std::io;
    use std::ffi::OsStr;
    use std::fs::File;

    pub fn open(path: &OsStr) -> io::Result<impl io::BufRead> {
        Ok(if path == "-" {
            Either::Left(io::stdin().lock())
        } else {
            Either::Right(io::BufReader::new(File::open(path)?))
        })
    }

相应的 create 函数留给读者作为练习。

功能

clap-parse

为所有类型实现 ValueParserFactory,并添加了所有类型的糟糕的 Clone 实现,以使 clap 满意。

HTTP 客户端

如果将 URL 传递给 Input::new,则它将执行 HTTP GET 操作。与仅通过管道传递 curl 输出相比,这具有优势,因为您知道输入大小,可以推断相关 URL,例如获取与 Cargo.lock 匹配的 Cargo.toml

如果将 URL 传递给 Output::new,则它将执行 HTTP PUT 操作。与仅通过管道传递给 curl 相比,主要优势是可以使用 OutputPath::create_with_len 在上传开始前设置大小,例如在向 S3 发送文件时需要。

http-ureq

捆绑了 ureq 作为 HTTP 客户端。

http-curl

捆绑了 curl 作为 HTTP 客户端。

依赖项

~2–13MB
~174K SLoC