#i18n #fl #embed #fluent #localization #macro #time

macro i18n-embed-fl

Macro to perform compile time checks when using the i18n-embed crate and the fluent localization system

11 releases (4 breaking)

0.5.0 Mar 18, 2021
0.4.0 Feb 4, 2021
0.3.1 Jan 11, 2021
0.2.0 Oct 17, 2020
0.1.5 Aug 28, 2020

#17 in Internationalization (i18n)

Download history 74/week @ 2020-12-22 867/week @ 2020-12-29 665/week @ 2021-01-05 458/week @ 2021-01-12 282/week @ 2021-01-19 286/week @ 2021-01-26 439/week @ 2021-02-02 237/week @ 2021-02-09 443/week @ 2021-02-16 507/week @ 2021-02-23 204/week @ 2021-03-02 498/week @ 2021-03-09 747/week @ 2021-03-16 492/week @ 2021-03-23 525/week @ 2021-03-30 690/week @ 2021-04-06

1,844 downloads per month
Used in 5 crates (3 directly)

MIT license

391 lines

i18n-embed-fl crates.io badge docs.rs badge license badge github actions badge

This crate provides a macro to perform compile time checks when using the i18n-embed crate and the fluent localization system.

See docs, and i18n-embed for more information.



Set up a minimal i18n.toml in your crate root to use with cargo-i18n (see cargo i18n for more information on the configuration file format):

# (Required) The language identifier of the language used in the
# source code for gettext system, and the primary fallback language
# (for which all strings must be present) when using the fluent
# system.
fallback_language = "en-GB"

# Use the fluent localization system.
# (Required) The path to the assets directory.
# The paths inside the assets directory should be structured like so:
# `assets_dir/{language}/{domain}.ftl`
assets_dir = "i18n"

Create a fluent localization file for the en-GB language in i18n/en-GB/{domain}.ftl, where domain is the rust path of your crate (_ instead of -):

hello-arg = Hello {$name}!

Simple set up of the FluentLanguageLoader, and obtaining a message formatted with an argument:

use i18n_embed::{
    fluent::{fluent_language_loader, FluentLanguageLoader},
use i18n_embed_fl::fl;
use rust_embed::RustEmbed;

#[folder = "i18n/"]
struct Localizations;

let loader: FluentLanguageLoader = fluent_language_loader!();
    .load_languages(&Localizations, &[loader.fallback_language()])

    "Hello \u{2068}Bob 23\u{2069}!",
    // Compile time check for message id, and the `name` argument,
    // to ensure it matches what is specified in the `fallback_language`'s
    // fluent resource file.
    fl!(loader, "hello-arg", name = format!("Bob {}", 23))

Convenience Macro

You will notice that this macro requires loader to be specified in every call. For you project you may have access to a statically defined loader, and you can create a convenience macro wrapper so this doesn't need to be imported and specified every time.

macro_rules! fl {
    ($message_id:literal) => {{
        i18n_embed_fl::fl!($crate::YOUR_STATIC_LOADER, $message_id)

    ($message_id:literal, $($args:expr),*) => {{
        i18n_embed_fl::fl!($crate::YOUR_STATIC_LOADER, $message_id, $($args), *)

This can now be invoked like so: fl!("message-id"), fl!("message-id", args) and fl!("message-id", arg = "value").


~66K SLoC