Skip to content
This repository has been archived by the owner on Aug 16, 2021. It is now read-only.

Localization #12

Open
U007D opened this issue Nov 4, 2017 · 3 comments
Open

Localization #12

U007D opened this issue Nov 4, 2017 · 3 comments

Comments

@U007D
Copy link
Contributor

U007D commented Nov 4, 2017

In the talk given on Nov. 2 2017 in SF, an audience member asked about "localization". I'm not sure what specific localization techniques were being referred to in the discussion (they were never specified), but I have been using the technique of putting all string resources (for a particular locale) into a (build-time-interchangeable) module.

I merely refer to a constant (const _ &'static str) by name wherever it is needed.

Unfortunately, referring to a const in a Failure display attribute does not appear to be supported:

OK:

#[derive(Debug, Fail)]
enum ErrorKind {
    #[fail(display = "argument validation error")]
...

Error (error: proc-macro derive panicked):

// in en_us constants module
pub const MSG_ERR_ARG_VALIDATION: &'static str = "argument validation error";

// in error module
#[derive(Debug, Fail)]
enum ErrorKind {
    #[fail(display = MSG_ERR_ARG_VALIDATION)]
...

While I understand that rich evaluations like method calls in attributes are not supported by Rust today, given how attributes are processed, can this be remedied for constants?

@durka
Copy link
Contributor

durka commented Nov 5, 2017

I think the problem is that the string given in the attribute is used as a format! string, and those must be literals (not constants).

@U007D
Copy link
Contributor Author

U007D commented Nov 5, 2017

Thanks for this tip, @durka. With that in mind, I tried

#[fail(display = "{}", MSG_ERR_ARG_VALIDATION)]

(with MSG_ERR_ARG_VALIDATION in scope, of course) which yielded error: proc-macro derive panicked... Couldn't find a field with this name!.

If #[fail()] could be relaxed to permit any binding currently in scope, that would serve as a good workaround for localization support. Possible?

@U007D
Copy link
Contributor Author

U007D commented Nov 7, 2017

As things stand today, it looks like manual display implementation is the only option if localization is required (which, in cases such as mine, it is):

use std::fmt;
use assayer::Error as AssayerError;

#[derive(Fail, Debug)]
pub enum Error {
    ArgValidation(#[cause] AssayerError),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", match *self {
            Error::ArgValidation(_) => { MSG_ERR_ARG_VALIDATION },
        })
    }
}

I'm open to thoughts on how to allow either basic const substitution or possibly even richer expression evaluation in a derive or a macro. Ideas?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants