summaryrefslogtreecommitdiffstats
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs85
1 files changed, 85 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs
index 2e23682..d513f20 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,6 +1,8 @@
#![allow(unused_braces)]
use crate::resp_types::RespLoginInfo;
+use std::borrow::Cow;
+use std::collections::HashMap;
use std::sync::Arc;
use trout::hyper::RoutingFailureExtHyper;
@@ -54,6 +56,89 @@ pub fn simple_response(
res
}
+lazy_static::lazy_static! {
+ static ref LANG_MAP: HashMap<unic_langid::LanguageIdentifier, fluent::FluentResource> = {
+ let mut result = HashMap::new();
+
+ result.insert(unic_langid::langid!("en"), fluent::FluentResource::try_new(include_str!("../res/lang/en.flt").to_owned()).expect("Failed to parse translation"));
+ result.insert(unic_langid::langid!("eo"), fluent::FluentResource::try_new(include_str!("../res/lang/eo.flt").to_owned()).expect("Failed to parse translation"));
+
+ result
+ };
+
+ static ref LANGS: Vec<unic_langid::LanguageIdentifier> = {
+ LANG_MAP.keys().cloned().collect()
+ };
+}
+
+pub struct Translator {
+ bundle: fluent::concurrent::FluentBundle<&'static fluent::FluentResource>,
+}
+impl Translator {
+ pub fn tr<'a>(&'a self, key: &str, args: Option<&'a fluent::FluentArgs>) -> Cow<'a, str> {
+ let mut errors = Vec::with_capacity(0);
+ let out = self.bundle.format_pattern(
+ self.bundle
+ .get_message(key)
+ .expect("Missing message in translation")
+ .value
+ .expect("Missing value for translation key"),
+ args,
+ &mut errors,
+ );
+ if !errors.is_empty() {
+ eprintln!("Errors in translation: {:?}", errors);
+ }
+
+ out
+ }
+}
+impl std::fmt::Debug for Translator {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+ write!(f, "Translator")
+ }
+}
+
+pub fn get_lang_for_headers(headers: &hyper::header::HeaderMap) -> Translator {
+ let default = unic_langid::langid!("en");
+ let languages = match headers
+ .get(hyper::header::ACCEPT_LANGUAGE)
+ .and_then(|x| x.to_str().ok())
+ {
+ Some(accept_language) => {
+ let requested = fluent_langneg::accepted_languages::parse(accept_language);
+ fluent_langneg::negotiate_languages(
+ &requested,
+ &LANGS,
+ Some(&default),
+ fluent_langneg::NegotiationStrategy::Filtering,
+ )
+ }
+ None => vec![&default],
+ };
+
+ let mut bundle = fluent::concurrent::FluentBundle::new(languages.iter().map(|x| *x));
+ for lang in languages {
+ if let Err(errors) = bundle.add_resource(&LANG_MAP[lang]) {
+ for err in errors {
+ match err {
+ fluent::FluentError::Overriding { .. } => {}
+ _ => {
+ eprintln!("Failed to add language resource: {:?}", err);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ Translator { bundle }
+}
+
+pub fn get_lang_for_req(req: &hyper::Request<hyper::Body>) -> Translator {
+ get_lang_for_headers(req.headers())
+}
+
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let backend_host = std::env::var("BACKEND_HOST").expect("Missing BACKEND_HOST");