我想实现一个在git存储库上操作的简单clap cli,但这对这个问题并不重要;它将有助于澄清我相信的问题。如果不是从存储库的根目录中运行,我正在尝试识别最惯用的退出方式。这里有三个选择,我不确定哪一个是好的。
做这些步骤的最佳方法是什么:
理想情况下,我将能够输出错误和使用。此外,子命令中还会出现其他错误,在这些情况下,我不确定最佳的退出方式。
考虑以下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(())
}这些可怕的、可使用的或可改进的东西中有任何或所有这些都是可以改进的吗?
我看到了寻求主观信息的闭幕式投票,但我想要的可能是比看起来更二进制的。当然,我会尊重社会人士的意愿,但我想知道,其中任何一项或全部是否因某些原因而严重超出常规,是有问题的。
发布于 2022-05-10 08:43:07
几点意见:
.map_err()而不是match将错误转换为另一个错误,它更紧凑,更易于阅读?运算符而不是return来向上传播错误。?操作符是一个简短的版本,“拆开如果确定,返回错误如果错误”,并使代码更容易阅读。下面是一个使用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(())
}```https://stackoverflow.com/questions/72182481
复制相似问题