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:
macrosis enabled by default and provides#[es_fluent_language].localized-langsformats 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:
| Trait | Description |
|---|---|
Default | Returns the variant matching fallback_language from i18n.toml |
FromStr | Parses "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 |
FluentMessage | Renders 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-langruntime hook. cargo es-fluent generatewill 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.