如何匹配因加入期货而导致的多种不同错误类型?

How to match on multiple different error types resulting from joining futures?

我正在使用库 thiserror 并希望匹配多个不同的错误。

我的main.rs:

let bus1_fut = bus1::start();
let bus2_fut = bus2::start();
match try_join!(
        bus1_fut,
        bus2_fut
    ) {
        Ok(_) => {}
        Err(e) => match e {
            Bus1Error::Error0 => info!("{}", e),
            Bus1Error::IOError(err) => error!("Failed to execute: {}", err),
            Bus2Error::Error1 => info!("{}", e),
            Bus2Error::IOError(err) => error!("Failed to execute: {}", err),
        }
    }

在一个单独的箱子中,business1.rs

#[derive(Error, Debug)]
pub enum Bus1Error {
    #[error("Error.")]
    Error0,
    #[error(transparent)]
    IOError(#[from] std::io::Error),
}

同样,在一个单独的板条箱中,business2.rs:

#[derive(Error, Debug)]
pub enum Bus2Error {
    #[error("Error.")]
    Error1,
    #[error(transparent)]
    IOError(#[from] std::io::Error),
}

函数 bus1::start()bus2::start() return Result<(), Bus1Error>Result<(), Bus2Error>

不幸的是,我得到了编译错误:

31 |       match try_join!(
33 | |         bus1_fut,
34 | |         bus2_fut
35 | |     ) {
   | |_____^ expected enum `Bus1Error`, found enum `Bus2Error`


    Bus2Error::Error1 => info!("{}", e),
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Bus1Error`, found enum `Bus2Error`

try_join 来自 tokio.

我不确定如何匹配这些不同的错误类型。

编辑:我尝试按如下方式实施 Shepmaster 提供的建议。

在我的 main.rs 我现在添加了:

#[derive(Error, Debug)]
pub enum MainError {
    #[error("Blah.")]
    Bus1Error(Bus1Error),
    #[error("Blah.")]
    Bus2Error(Bus2Error),
}

但是,我仍然遇到同样的错误。我现在是否必须调整 bus1::start()bus2::start() 的 return 值来匹配我的 MainError?对我来说,这没有意义,因为我不想在这两个板条箱中包含来自 main.rs 的任何代码。

感谢 Shepmaster 我能够通过以下方式解决此问题:

在我的 main.rs:

use futures::TryFutureExt;


#[derive(Error, Debug)]
pub enum MainError {
    #[error("Blah.")]
    Bus1Err(#[from] Bus1Error),
    #[error("Blah.")]
    Bus2Err(#[from] Bus2Error),
}

...

let bus1_fut = bus1::start();
let bus2_fut = bus2::start();
match try_join!(
        bus1_fut.map_err(MainError::from),
        bus2_fut.map_err(MainError::from)
    ) {
        Ok(_) => {}
        Err(e) => match e {
            MainError::Bus1Err => info!("{}", e),
            MainError::Bus2Err => info!("{}", e),
        }
    }