|
|
|
@ -1,5 +1,6 @@
|
|
|
|
|
use derive_more::From;
|
|
|
|
|
use rocket_dyn_templates::tera::{self, Value};
|
|
|
|
|
use serde::Serialize;
|
|
|
|
|
use std::{
|
|
|
|
|
collections::HashMap,
|
|
|
|
|
fs::{self, File},
|
|
|
|
@ -16,9 +17,11 @@ pub enum LoadCatalogsError {
|
|
|
|
|
MissingDefaultLanguage,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const DEFAULT: &str = "ja";
|
|
|
|
|
pub const DEFAULT: &str = "ja";
|
|
|
|
|
|
|
|
|
|
pub fn load_catalogs() -> Result<HashMap<String, Catalog>, LoadCatalogsError> {
|
|
|
|
|
type Catalogs = HashMap<String, Catalog>;
|
|
|
|
|
|
|
|
|
|
pub fn load_catalogs() -> Result<(Catalogs, Vec<LangCode>), LoadCatalogsError> {
|
|
|
|
|
let mut catalogs = HashMap::new();
|
|
|
|
|
for file in fs::read_dir("i18n")? {
|
|
|
|
|
let file = file?;
|
|
|
|
@ -51,19 +54,58 @@ pub fn load_catalogs() -> Result<HashMap<String, Catalog>, LoadCatalogsError> {
|
|
|
|
|
if !catalogs.contains_key(DEFAULT) {
|
|
|
|
|
return Err(LoadCatalogsError::MissingDefaultLanguage);
|
|
|
|
|
}
|
|
|
|
|
Ok(catalogs)
|
|
|
|
|
let langs = catalogs
|
|
|
|
|
.iter()
|
|
|
|
|
.map(|(code, catalog)|
|
|
|
|
|
LangCode {
|
|
|
|
|
code: code.clone(),
|
|
|
|
|
name: catalog
|
|
|
|
|
.gettext("lang")
|
|
|
|
|
.to_owned(),
|
|
|
|
|
}
|
|
|
|
|
).collect();
|
|
|
|
|
Ok((catalogs, langs))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn i18n_filter(
|
|
|
|
|
value: &Value,
|
|
|
|
|
_args: &HashMap<String, Value>,
|
|
|
|
|
catalogs: &HashMap<String, Catalog>,
|
|
|
|
|
args: &HashMap<String, Value>,
|
|
|
|
|
catalogs: &Catalogs,
|
|
|
|
|
) -> tera::Result<Value> {
|
|
|
|
|
let key = value
|
|
|
|
|
.as_str()
|
|
|
|
|
.ok_or_else(|| tera::Error::msg("The translation key must be a string"))?;
|
|
|
|
|
|
|
|
|
|
let translation = catalogs.get(DEFAULT).expect("Missing catalog").gettext(key);
|
|
|
|
|
let langs = args
|
|
|
|
|
.get("lang")
|
|
|
|
|
.map(|value| value.as_array())
|
|
|
|
|
.flatten()
|
|
|
|
|
.map(|array| {
|
|
|
|
|
let mut langs = Vec::with_capacity(array.len());
|
|
|
|
|
for lang in array {
|
|
|
|
|
langs.push(lang.as_str().unwrap());
|
|
|
|
|
}
|
|
|
|
|
langs
|
|
|
|
|
})
|
|
|
|
|
.unwrap_or_else(|| vec![DEFAULT]);
|
|
|
|
|
for lang in langs {
|
|
|
|
|
if let Some(catalog) = catalogs.get(lang) {
|
|
|
|
|
return Ok(Value::String(catalog.gettext(key).to_owned()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
panic!("Missing catalog");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(Value::String(translation.to_owned()))
|
|
|
|
|
#[derive(Serialize)]
|
|
|
|
|
pub struct LangCode {
|
|
|
|
|
pub code: String,
|
|
|
|
|
pub name: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn langs_filter(
|
|
|
|
|
_value: &Value,
|
|
|
|
|
_args: &HashMap<String, Value>,
|
|
|
|
|
langs: &Vec<LangCode>,
|
|
|
|
|
) -> tera::Result<Value> {
|
|
|
|
|
Ok(serde_json::to_value(langs).unwrap())
|
|
|
|
|
}
|