Изучая 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, должен будет заботиться об этом параметре типа, который на практике никого не волнует.
Как мне идиоматически поступить в этой ситуации?

Я рекомендую вам использовать определенные типы или добавить свой собственный вариант. 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
}
}