/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use super::LangStrings; use anyhow::Context; use fluent::{bundle::FluentBundle, FluentResource}; use unic_langid::LanguageIdentifier; const FALLBACK_FTL_FILE: &str = include_str!(mozbuild::srcdir_path!( "/toolkit/locales/en-US/crashreporter/crashreporter.ftl" )); const FALLBACK_BRANDING_FILE: &str = include_str!(mozbuild::srcdir_path!( "/browser/branding/official/locales/en-US/brand.ftl" )); /// Localization language information. #[derive(Debug, Clone)] pub struct LanguageInfo { pub identifier: String, pub ftl_definitions: String, pub ftl_branding: String, } impl Default for LanguageInfo { fn default() -> Self { Self::fallback() } } impl LanguageInfo { /// Get the fallback bundled language information (en-US). pub fn fallback() -> Self { LanguageInfo { identifier: "en-US".to_owned(), ftl_definitions: FALLBACK_FTL_FILE.to_owned(), ftl_branding: FALLBACK_BRANDING_FILE.to_owned(), } } /// Load strings from the language info. pub fn load_strings(self) -> anyhow::Result { let Self { identifier: lang, ftl_definitions: definitions, ftl_branding: branding, } = self; let langid = lang .parse::() .with_context(|| format!("failed to parse language identifier ({lang})"))?; let rtl = langid.character_direction() == unic_langid::CharacterDirection::RTL; let mut bundle = FluentBundle::new_concurrent(vec![langid]); fn add_ftl( bundle: &mut FluentBundle, ftl: String, ) -> anyhow::Result<()> { let resource = FluentResource::try_new(ftl) .ok() .context("failed to create fluent resource")?; bundle .add_resource(resource) .ok() .context("failed to add fluent resource to bundle")?; Ok(()) } add_ftl(&mut bundle, branding).context("failed to add branding")?; add_ftl(&mut bundle, definitions).context("failed to add localization")?; Ok(LangStrings::new(bundle, rtl)) } }