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
18,475 次每月下载
在 15 个crate 中使用
85KB
1.5K SLoC
clio
clio 是一个用于解析 CLI 文件名的 Rust 库。
它实现了当文件名是 ""
时,将数据发送到 stdin/stdout 的标准 Unix 约定。通过 clap-parse
功能,它还增加了一些有用的过滤器来验证来自命令行参数的路径,例如检查路径是否存在或是否是目录。
用法
Input
和 Output
可以直接从 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(())
}
如果您想延迟打开文件,可以使用 InputPath
和 OutputPath
。这可以避免在错误发生得非常早时留下空的输出文件。它们会在创建时检查路径是否存在、是否是文件,并且从理论上讲可以打开以获取更友好的错误信息。由于这可能会留下 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