You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have a multi crate project with the following structure:
|- nih
|- data
| |- i18n
| |- en-GB
| |- nih_i18n.ftl <-- Why do I need this file?
| |- nih.ftl
|- nih
| |- i18n.toml <-- Why do I need this file?
| |- ...
|- nih_i18n
| |- i18n.toml <-- Why do I need this file?
| |- ...
|- i18n.toml
|- ...
The docs say that all subcrates will be treated as part of the parent crate, unless they have their own i18n.toml file. If I remove either of these files from the subcrates, I get the following errors depending on which file I remove:
error: proc macro panicked
--> nih_i18n\src\lib.rs:30:44
|
30 | let loader: FluentLanguageLoader = fluent_language_loader!();
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: message: fluent_language_loader!() had a problem reading i18n config file "D:\\Dev\\nih\\nih_i18n\\i18n.toml": Cannot read file "D:\\Dev\\nih\\nih_i18n\\i18n.toml" in the current working directory Ok("D:\\Dev\\nih") because The system cannot find the file specified. (os error 2).
or
error: fl!() had a problem reading i18n config file "D:\\Dev\\nih\\nih\\i18n.toml": Cannot read file "D:\\Dev\\nih\\nih\\i18n.toml" in the current working directory Ok("D:\\Dev\\nih") because The system cannot find the file specified. (os error 2).
= help: Try creating the `i18n.toml` configuration file.
--> nih\src\main.rs:28:27
|
28 | window.set_title(&fl!("hello-world"));
| ^^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `$crate::i18n_embed_fl::fl` which comes from the expansion of the macro `fl` (in Nightly builds, run with -Z macro-backtrace for more info)
Why do the subcrates need the individual i18n.toml files? I can perhaps understand why it is needed in the nih crate where I have translations, although it is surprising that the global file is not used. I don't understand why it is needed in the nih_i18n crate, where there are not translations and I'm just setting up the language loader, localiser and re-exporting the fl macro as per the example:
use std::sync::OnceLock;
use i18n_embed::{
fluent::{fluent_language_loader, FluentLanguageLoader},
DefaultLocalizer, DesktopLanguageRequester, I18nEmbedError, LanguageLoader, Localizer,
RustEmbedNotifyAssets,
};
pub use i18n_embed_fl;
use nih_error::Error;
use rust_embed::RustEmbed;
#[derive(RustEmbed)]
#[folder = "../data/i18n/"]
pub struct LocalizationsEmbed;
pub fn get_localisations() -> &'static RustEmbedNotifyAssets<LocalizationsEmbed> {
pub static LOCALIZATIONS: OnceLock<RustEmbedNotifyAssets<LocalizationsEmbed>> = OnceLock::new();
LOCALIZATIONS.get_or_init(|| {
RustEmbedNotifyAssets::new(
std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("data/i18n/"),
)
})
}
pub fn get_language_loader() -> &'static FluentLanguageLoader {
static LANGUAGE_LOADER: OnceLock<FluentLanguageLoader> = OnceLock::new();
LANGUAGE_LOADER.get_or_init(|| {
let loader: FluentLanguageLoader = fluent_language_loader!();
// Load the fallback langauge by default so that users of the
// library don't need to if they don't care about localization.
loader
.load_fallback_language(get_localisations())
.expect("Error while loading fallback language");
loader
})
}
#[macro_export]
macro_rules! fl {
($message_id:literal) => {{
$crate::i18n_embed_fl::fl!($crate::get_language_loader(), $message_id)
}};
($message_id:literal, $($args:expr),*) => {{
$crate::i18n_embed_fl::fl!($crate::get_language_loader(), $message_id, $($args), *)
}};
}
fn localizer() -> DefaultLocalizer<'static> {
DefaultLocalizer::new(get_language_loader(), get_localisations())
}
pub fn init_i18n() -> Result<(), Error> {
let localiser = localizer()
.with_autoreload()
.expect("failed to enable localisation autoreloader");
let requested_languages = DesktopLanguageRequester::requested_languages();
nih_logging::debug!("{:?}", &requested_languages);
localiser
.select(&requested_languages)
.map_err(failed_to_load_i18n_languages)?;
Ok(())
}
fn failed_to_load_i18n_languages(error: I18nEmbedError) -> Error {
Error::new("failed to load languages for i18n").with_source(error)
}
Then, when this is working with all these extra config files, it selects the wrong translation. Below are my translation files:
To add a bit more information, if the nih_i18n.ftl translation file is missing, I get the following error:
Exception thrown at 0x00007FFE6723FB4C in nih.exe: Microsoft C++ exception: ?? ::st_panic at memory location 0x000000F6B4CFE5B0.
Loaded 'C:\Windows\System32\kernel.appcore.dll'.
Which appears to originate somewhere in LanguageLoader:
If instead the nih.ftl translation file is missing, I get the following error:
error: fl!() was unable to load the localization file for the `fallback_language` ("en-GB"): en-GB/nih.ftl
= help: Try creating the required fluent localization file.
--> nih\src\main.rs:26:27
|
26 | window.set_title(&fl!("hello-world"));
| ^^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `$crate::i18n_embed_fl::fl` which comes from the expansion of the macro `fl` (in Nightly builds, run with -Z macro-backtrace for more info)
If in nih.ftl I change the message ID to something else, the error changes to:
error: fl!() `message_id` validation failed. `message_id` of "hello-world" does not exist in the `fallback_language` ("en-GB")
= help: Enter the correct `message_id` or create the message in the localization file if the intended message does not yet exist.
= help: Perhaps you are looking for one of the following messages?
hello-world2
--> nih\src\main.rs:26:31
|
26 | window.set_title(&fl!("hello-world"));
| ^^^^^^^^^^^^^
error: could not compile `nih` (bin "nih") due to 1 previous error
But if I instead change the message ID in nih_i18n.ftl to something else, I get the following output:
Overall, this is very confusing and I'm hoping that there is either some configuration that I've missed or an easy fix in the code?
I have a multi crate project with the following structure:
The contents of my main
i18n.toml
is:The docs say that all subcrates will be treated as part of the parent crate, unless they have their own
i18n.toml
file. If I remove either of these files from the subcrates, I get the following errors depending on which file I remove:or
Why do the subcrates need the individual
i18n.toml
files? I can perhaps understand why it is needed in thenih
crate where I have translations, although it is surprising that the global file is not used. I don't understand why it is needed in thenih_i18n
crate, where there are not translations and I'm just setting up the language loader, localiser and re-exporting thefl
macro as per the example:Then, when this is working with all these extra config files, it selects the wrong translation. Below are my translation files:
nih_i18n.ftl:
nih.ftl:
And the usage code in
nih/src/main.rs
:But as you can see, it does not use the correct translation:
What I was expecting:
i18n.toml
file at the project root.nih_i18n.ftl
for a crate where I do no localisation.fl!
invocation in thenih
crate to use the translation specified innih.ftl
.The text was updated successfully, but these errors were encountered: