Как использовать thiserror для пересылки ошибки с параметром универсального типа

Изучая Rust, я использую ящик thiserror для переноса некоторых исключений.

Это исключение, которое я хочу обернуть из ящика unrar:

#[derive(PartialEq)]
pub struct UnrarError<T> {
    pub code: Code,
    pub when: When,
    pub data: Option<T>,
}

Мой собственный код таков:

#[derive(Debug, Error)]
pub enum MyError {

    #[error(transparent)]
    Io(#[from] io::Error),

    #[error(transparent)]
    Unrar(#[from] unrar::error::UnrarError), // <-- missing generics

    #[error("directory already exists")]
    DirectoryExists,
}

Компилятор жалуется на отсутствие параметра типа generics в файле UnrarError.

Итак, я могу добавить параметр типа:

#[derive(Debug, Error)]
pub enum MyError<T> {

    #[error(transparent)]
    Io(#[from] io::Error),

    #[error(transparent)]
    Unrar(#[from] unrar::error::UnrarError<T>),

    #[error("directory already exists")]
    DirectoryExists,
}

Но если я это сделаю, то теперь весь мой код, использующий MyError, должен будет заботиться об этом параметре типа, который на практике никого не волнует.

Как мне идиоматически поступить в этой ситуации?

Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
0
0
97
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я рекомендую вам использовать определенные типы или добавить свой собственный вариант. UnrarError разработан, чтобы быть универсальным там, где он не должен быть универсальным.

Попробуйте следующее:

#[derive(Debug, Error)]
pub enum MyError {

    #[error(transparent)]
    Io(#[from] io::Error),

    #[error(transparent)]
    Unrar(#[from] unrar::error::UnrarError<OpenArchive>),

    #[error(transparent)]
    UnrarProcessing(#[from] unrar::error::UnrarError<Vec<Entry>>),

    #[error("directory already exists")]
    DirectoryExists,
}

Или как я предпочитаю делать в этом случае:

#[derive(Debug, Error)]
pub enum MyError {

    #[error(transparent)]
    Io(#[from] io::Error),

    #[error("unrar error")]
    Unrar,

    #[error("directory already exists")]
    DirectoryExists,
}

impl<T> From<unrar::error::UnrarError<T>> for MyError {
    fn from(err: unrar::error::UnrarError<T>) -> Self {
        // Get details from the error you want,
        // or even implement for both T variants.
        Self::Unrar
    }
}

Другие вопросы по теме