Open
Description
Howdy! I'm the author of SNAFU an error type library. I think it would be very powerful to be able to use Fluent to enhance error types with localized error messages.
An error type enhanced with SNAFU looks something like this:
#[derive(Debug, Snafu)]
enum OneError {
#[snafu(display("Something bad happened with the value {}", value))]
Something { value: i32 },
#[snafu(display("Another bad thing happened to user {}: {}", username, source))]
Another { source: AnotherError, username: String },
}
This implements all the appropriate error traits, but Display
is hard-coded to whatever the programmer typed.
In my head, I'm wondering if the two crates could be combined to create something used like this:
#[derive(Debug, Snafu)]
enum OneError {
#[snafu(display("Something bad happened with the value {}", value))]
#[fluent("one-error-something")]
Something { value: i32 },
#[snafu(display("Another bad thing happened to user {}: {}", username, source))]
#[fluent("one-error-another")]
Another { source: AnotherError, username: String },
}
struct FluentError<E> {
db: FluentData, // A reference, Rc, Arc; whatever
err: E,
}
use std::fmt;
impl fmt::Display for FluentError<E>
where
E: IntoFluent + Error,
{
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self.db.format(self.e) {
Ok(s) => s.fmt(f),
Err(_) => self.e.fmt(f),
}
}
}
Highlights:
- A
fluent
procedural macro identifies the key of the error and implements a newIntoFluent
trait. - The trait returns the
HashMap
of properties and the key. - A new type wraps any error type that also implements
IntoFluent
, using the translation available from fluent or falling back to the built-inDisplay
implementation.
For Fluent's side, I think that everything I just described should be agnostic of the error library. I believe that SNAFU would just be a great fit for making use of it!