Skip to content

Fluent × SNAFU collaboration #107

Open
@shepmaster

Description

@shepmaster

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:

  1. A fluent procedural macro identifies the key of the error and implements a new IntoFluent trait.
  2. The trait returns the HashMap of properties and the key.
  3. A new type wraps any error type that also implements IntoFluent, using the translation available from fluent or falling back to the built-in Display 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!

Metadata

Metadata

Labels

design-decisionIssues pending design decision, usually Rust specificenhancement

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions