首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >返回错误并在clap cli中优雅地退出

返回错误并在clap cli中优雅地退出
EN

Stack Overflow用户
提问于 2022-05-10 07:47:20
回答 1查看 656关注 0票数 0

我想实现一个在git存储库上操作的简单clap cli,但这对这个问题并不重要;它将有助于澄清我相信的问题。如果不是从存储库的根目录中运行,我正在尝试识别最惯用的退出方式。这里有三个选择,我不确定哪一个是好的。

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

  1. 检查我是否已从爬行根运行
  2. 如果继续,如果没有退出
  3. 如果没有发出命令,则生成帮助。
  4. 如果发出命令,则运行该命令。

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

考虑以下cli定义:

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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(())
}

这些可怕的、可使用的或可改进的东西中有任何或所有这些都是可以改进的吗?

我看到了寻求主观信息的闭幕式投票,但我想要的可能是比看起来更二进制的。当然,我会尊重社会人士的意愿,但我想知道,其中任何一项或全部是否因某些原因而严重超出常规,是有问题的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-05-10 08:43:07

我个人非常喜欢错误包装库,如不管怎样,爱尔米特

几点意见:

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

下面是一个使用anyhow的示例

代码语言:javascript
复制
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(())
}```
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72182481

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档