Want to contribute? Fork me on Codeberg.org!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

56 lines
1.7 KiB

use std::{collections::HashMap, fs::{self, File}, io::BufReader, process::Command};
use derive_more::From;
use rocket_dyn_templates::tera::{self, Value};
use gettext::Catalog;
#[derive(From, Debug)]
pub enum LoadCatalogsError {
Io(std::io::Error),
Parse(gettext::Error),
MissingDefaultLanguage,
}
const DEFAULT: &str = "ja";
pub fn load_catalogs() -> Result<HashMap<String, Catalog>, LoadCatalogsError> {
let mut catalogs = HashMap::new();
for file in fs::read_dir("i18n")? {
let file = file?;
let path = file.path();
if !file.file_type()?.is_file() || !path.extension().map(|extension| extension.eq("po")).unwrap_or(false) {
continue;
}
let language_code = path
.file_stem()
.expect("Invalid translation file name")
.to_string_lossy()
.to_string();
let po_file_path = path;
let mo_file_path = format!("i18n/{}.mo", language_code);
Command::new("msgfmt")
.arg(&po_file_path)
.arg("-o")
.arg(&mo_file_path)
.output()?;
catalogs.insert(language_code, Catalog::parse(BufReader::new(File::open(mo_file_path)?))?);
}
if !catalogs.contains_key(DEFAULT) {
return Err(LoadCatalogsError::MissingDefaultLanguage);
}
Ok(catalogs)
}
pub fn i18n_filter(value: &Value, _args: &HashMap<String, Value>, catalogs: &HashMap<String, Catalog>) -> 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);
Ok(Value::String(translation.to_owned()))
}