I've started using the following Error
configuration for some simple libraries I've been working on:
pub mod err {
use std::{error, fmt, result};
macro_rules! from {
($t: ty) => {
impl ::std::convert::From<$t> for Error {
fn from(e: $t) -> Self {
Error::Boxed(e.into())
}
}
}
}
#[derive(Debug)]
pub enum Error {
All,
My,
Var(Iants),
Boxed(Box<error::Error + Send + Sync>)
}
impl error::Error for Error {
fn description(&self) -> &str {
match *self {
/* ... */
Error::Boxed(ref e) => { e.description() },
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
error::Error::description(self).fmt(f)
}
}
pub type Result<T> = result::Result<T, Error>;
from!(::std::string::FromUtf8Error);
from!(::std::str::Utf8Error);
from!(::std::ffi::NulError);
/* ... */
}
I'm pretty happy with this—it lets me generate my own errors and handle external errors pretty easily.
A couple questions:
Is it bad form to "throw away" the type info like this for the errors I am boxing?
Is there an easier way to do this? For example, I could do away with my from!
macro and calls if I could do something like:
impl<E> From<E> for MyErrorEnum
where E: ::std::error::Error and E != MyErrorEnum {}
I think this would be possible with negative trait bounds (which is not currently available in Rust).
Are there any other issues I'm missing?