gpt4 book ai didi

rust - 在 clap cli 中返回错误并优雅退出

转载 作者:行者123 更新时间:2023-12-03 08:06:30 30 4
gpt4 key购买 nike

我想实现一个在 git 存储库上运行的简单 clap cli,但这对问题并不重要;我相信这将有助于澄清。我试图确定如果不从存储库的根运行的话,退出时出现错误的最惯用的方法。这里有三个选项;我不确定是否有好的。

执行这些步骤的最佳方法是什么:

  1. 检查我是否从存储库根目录运行
  2. 如果是则继续,如果不是则退出
  3. 如果没有给出命令,则生成帮助
  4. 如果给出命令,则运行该命令

理想情况下,我能够输出错误和用法。此外,子命令中还会发生其他错误,我不确定在这些情况下优雅退出的最佳方法。

考虑以下 cli 定义:

use clap::ErrorKind::Io;
use clap::{Parser, Subcommand};
use git2::Repository;
use std::process;

#[derive(Debug, Parser)]
#[clap(author, version, about, long_about = None)]
struct Cli {
#[clap(subcommand)]
command: Commands,
}

#[derive(Debug, Subcommand)]
enum Commands {
/// Do a thing.
Do,
}

我目前看到的三个主要选项是:

选项 1

fn main() -> Result<(), String> {
let repo = match Repository::open(".") {
Ok(repo) => repo,
Err(_) => return Err("must be run from root of repository".to_owned()),
};
let args = Cli::parse();
match args.command {
Commands::Do => {
println!("{:?}: Doing a thing with the repository.", repo.workdir());
}
}
Ok(())
}

选项 2

fn main() {
let repo = match Repository::open(".") {
Ok(repo) => repo,
Err(_) => {
eprintln!("{}", "must be run from root of repository".to_owned());
process::exit(1);
}
};
let args = Cli::parse();
match args.command {
Commands::Do => {
println!("{:?}: Doing a thing with the repository.", repo.workdir());
}
}
}

选项 3

fn main() -> clap::Result<(), clap::Error> {
let repo = match Repository::open(".") {
Ok(repo) => repo,
Err(_) => return Err(clap::Error::raw(Io, "not in repo")),
};
let args = Cli::parse();
match args.command {
Commands::Do => {
println!("{:?}: Doing a thing with the repository.", repo.workdir());
}
}
Ok(())
}

这些中的任何一个或全部是可怕的、有用的还是可以改进的?


我看到了寻求主观信息的结束投票,但我所追求的可能比看起来更加二元。我当然会尊重社区的意愿,但我想知道是否有任何或所有这些都严重不符合规范,或者由于某种原因存在问题。

最佳答案

我个人非常喜欢错误包装库,例如 anyhow , eyremiette .

一些评论:

  • 考虑使用 .map_err() 而不是 match 将错误转换为另一个错误,它更紧凑且更易于阅读
  • 考虑使用 ? 运算符而不是 return 来向上传播错误。 ? 运算符是“如果 Ok 则展开,如果 Err 则返回错误”的简短版本,使代码更易于阅读。

这是一个使用 anyhow 的示例:

fn main() -> anyhow::Result<()> {
let repo = Repository::open(".").map_err(|_| anyhow!("must be run from root of repository"))?;
let args = Cli::parse();
match args.command {
Commands::Do => {
println!("{:?}: Doing a thing with the repository.", repo.workdir());
}
}
Ok(())
}

关于rust - 在 clap cli 中返回错误并优雅退出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72182481/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com