Moving i18n to sepparate module

This commit is contained in:
2021-08-13 16:24:56 +02:00
parent be95cf68fc
commit 039a2b5e23
9 changed files with 44 additions and 7 deletions
+1
View File
@@ -27,6 +27,7 @@ qrcode = "0.12"
image = "0.23"
pslink-shared = { version="0.4.1-alpha.0", path = "../shared" }
pslink-locales = { version="0.4.1-alpha.0", path = "../locales" }
[dependencies.web-sys]
version = "0.3"
-97
View File
@@ -1,97 +0,0 @@
//! This modules contains the parts for making the app translatable.
use std::sync::Arc;
use fluent::{FluentArgs, FluentBundle, FluentResource};
use pslink_shared::datatypes::Lang;
use unic_langid::LanguageIdentifier;
/// A struct containing the data, functions and the current language to query the localized strings.
#[derive(Clone)]
pub struct I18n {
lang: Lang,
ftl_bundle: Arc<FluentBundle<FluentResource>>,
}
impl std::fmt::Debug for I18n {
/// On debug print skip the bundle
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.lang)
}
}
impl I18n {
/// Create a new translator struct
#[must_use]
pub fn new(lang: Lang) -> Self {
let ftl_bundle = Arc::new(Self::create_ftl_bundle(lang));
Self { lang, ftl_bundle }
}
/// Get the current language
#[must_use]
pub const fn lang(&self) -> &Lang {
&self.lang
}
/// Set the current language
pub fn set_lang(&mut self, lang: Lang) {
self.lang = lang;
self.ftl_bundle = Arc::new(Self::create_ftl_bundle(lang));
}
/// Get a localized string. Optionally with parameters provided in `args`.
pub fn translate(&self, key: impl AsRef<str>, args: Option<&FluentArgs>) -> String {
// log!(key.as_ref());
let msg = self
.ftl_bundle
.get_message(key.as_ref())
.expect("Failed to get fluent message for key {}");
let pattern = msg.value().expect("Failed to parse pattern");
self.ftl_bundle
.format_pattern(pattern, args, &mut vec![])
.to_string()
}
/// Prettyprint the language name
#[must_use]
pub const fn label(&self) -> &'static str {
match self.lang {
Lang::EnUS => "English (US)",
Lang::DeDE => "Deutsch (Deutschland)",
}
}
/// include the fluent messages into the binary
#[must_use]
pub const fn ftl_messages(lang: Lang) -> &'static str {
macro_rules! include_ftl_messages {
( $lang_id:literal ) => {
include_str!(concat!("../../locales/", $lang_id, "/main.ftl"))
};
}
match lang {
Lang::EnUS => include_ftl_messages!("en"),
Lang::DeDE => include_ftl_messages!("de"),
}
}
#[must_use]
pub fn language_identifier(lang: Lang) -> LanguageIdentifier {
lang.as_ref()
.parse()
.expect("parse Lang to LanguageIdentifier")
}
/// Create and initialize a fluent bundle.
#[must_use]
pub fn create_ftl_bundle(lang: Lang) -> FluentBundle<FluentResource> {
let ftl_resource = FluentResource::try_new(Self::ftl_messages(lang).to_owned())
.expect("parse FTL messages");
let mut bundle = FluentBundle::new(vec![Self::language_identifier(lang)]);
bundle.add_resource(ftl_resource).expect("add FTL resource");
bundle
}
}
+2 -3
View File
@@ -1,5 +1,4 @@
//! The admin interface of pslink. It communicates with the server mostly via https and json.
pub mod i18n;
pub mod navigation;
pub mod pages;
@@ -13,7 +12,7 @@ use seed::window;
use seed::IF;
use seed::{attrs, button, div, input, label, log, prelude::*, App, Url, C};
use crate::i18n::I18n;
use pslink_locales::I18n;
// ------ ------
// Init
@@ -45,7 +44,7 @@ struct Model {
index: usize,
location: Location,
page: Page,
i18n: i18n::I18n,
i18n: I18n,
user: Loadable<User>,
login_form: LoginForm,
login_data: LoginUser,
+2 -1
View File
@@ -1,12 +1,13 @@
//! Create the top menu of the app
use fluent::fluent_args;
use pslink_locales::I18n;
use pslink_shared::{
apirequests::users::Role,
datatypes::{Lang, User},
};
use seed::{a, attrs, div, li, nav, nodes, ol, prelude::*, Url, C};
use crate::{i18n::I18n, Msg};
use crate::Msg;
/// Generate the top navigation menu of all pages.
///
+2 -1
View File
@@ -4,6 +4,7 @@ use std::ops::Deref;
use enum_map::EnumMap;
use fluent::fluent_args;
use image::{DynamicImage, ImageOutputFormat, Luma};
use pslink_locales::I18n;
use qrcode::{render::svg, QrCode};
use seed::{
a, attrs, div, h1, img, input, log, nodes, prelude::*, raw, section, span, table, td, th, tr,
@@ -20,7 +21,7 @@ use pslink_shared::{
datatypes::{FullLink, Lang, Loadable, User},
};
use crate::{get_host, i18n::I18n, unwrap_or_return};
use crate::{get_host, unwrap_or_return};
/// Setup the page
pub fn init(mut url: Url, orders: &mut impl Orders<Msg>, i18n: I18n) -> Model {
+2 -1
View File
@@ -1,6 +1,7 @@
//! List all users in case an admin views it, list the "self" user otherwise.
use enum_map::EnumMap;
use pslink_locales::I18n;
use pslink_shared::{
apirequests::general::{Operation, Ordering},
apirequests::{
@@ -13,7 +14,7 @@ use seed::{a, attrs, div, h1, input, log, p, prelude::*, section, table, td, th,
/*
* init
*/
use crate::{i18n::I18n, unwrap_or_return};
use crate::unwrap_or_return;
#[must_use]
pub fn init(mut url: Url, orders: &mut impl Orders<Msg>, i18n: I18n) -> Model {
orders.send_msg(Msg::Query(UserQueryMsg::Fetch));