Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Language enum

The #[es_fluent_language] macro generates a typed enum from the locale directories in assets_dir. Use it to initialize a manager, switch locales, or build a language picker without maintaining a second list of locale strings.

Setup

Add the es-fluent-lang crate:

[dependencies]
es-fluent-lang = "0.18"

# Add this when the application iterates the generated enum.
strum = { version = "0.28", features = ["derive"] }

Feature flags:

  • macros is enabled by default and provides #[es_fluent_language].
  • localized-langs formats language names in the currently selected UI language instead of as autonyms.

For wasm32 builds, default generated language enums emit the force-link keepalive across managers, including Dioxus and Bevy.

Usage

Define an empty enum and annotate it with #[es_fluent_language]:

use es_fluent_lang::es_fluent_language;
use strum::EnumIter;

#[es_fluent_language]
#[derive(EnumIter)]
pub enum Languages {}

The macro derives Clone, Copy, Debug, Eq, Hash, and PartialEq automatically. Add derives such as EnumIter only when your application needs them.

If your assets_dir contains the same locales as the executable README example (en, fr-FR, and zh-CN), the macro expands this into:

pub enum Languages {
    En,
    FrFr,
    ZhCn,
}

The macro also generates these trait implementations:

TraitDescription
DefaultReturns the variant matching fallback_language from i18n.toml
FromStrParses "en", "fr-FR", or "zh-CN" into the matching variant
TryFrom<&LanguageIdentifier>Converts from a borrowed unic-langid identifier
TryFrom<LanguageIdentifier>Converts from an owned unic-langid identifier
Into<LanguageIdentifier>Converts back to a unic-langid identifier
FluentMessageRenders language labels through a manager

If the configured fallback language is not present as a locale directory, the macro still adds it to the enum so Default always has a valid variant.

Use the enum with managers

The Languages enum plugs directly into manager initialization:

use es_fluent_manager_embedded as manager;

let i18n = manager::EmbeddedI18n::try_new_with_language(Languages::En)?;

Since it implements Into<LanguageIdentifier>, you can pass variants anywhere a LanguageIdentifier is expected.

Render language-name labels

Each variant can be rendered through an explicit manager with i18n.localize_message(&language). The macro implements FluentMessage directly, and the crate formats those labels from ICU4X display-name data, so a language picker can display localized names:

// Prints the language name in its native script
println!("{}", i18n.localize_message(&Languages::FrFr)); // → "français"

By default, names are autonyms: FrFr renders as français and ZhCn renders as 中文. With the localized-langs feature, the same ICU4X data is formatted in the currently selected UI language instead, so an English UI can render French and Chinese.

For a language picker, iterate your generated enum, render each label through the active manager, and pass the selected variant back to the manager:

use strum::IntoEnumIterator as _;

for language in Languages::iter() {
    let label = i18n.localize_message(&language);
    println!("{language:?}: {label}");
}

i18n.select_language(Languages::FrFr)?;

The runtime uses the shared ICU4X/CLDR fallback chain when exact display-name data is missing. Use custom mode when you need project-specific labels or fully custom names for unsupported locale tags.

The built-in language-name module follows successful manager locale switches but does not count as application content support. A manager still reports an unsupported locale when no application translation module can serve it.

Custom mode

By default, the macro links to the built-in es-fluent-lang runtime without registering another translation module. If you want to provide your own translations for language names (for example, project-specific labels or exact wording control), use custom mode:

#[es_fluent_language(custom)]
#[derive(EnumIter)]
pub enum Languages {}

In custom mode:

  • The macro skips the built-in es-fluent-lang runtime hook.
  • cargo es-fluent generate will create keys for the enum in your FTL files.
  • You provide your own translations instead of using ICU4X-backed labels.
  • Use this when your app ships custom language-name translations for project-specific or otherwise unsupported locale tags.