Created
July 3, 2019 18:37
-
-
Save rust-play/b2ea5e7df918c9562aeeaf118f88de0e to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(proc_macro_hygiene, decl_macro)] | |
#[macro_use] | |
extern crate rocket; | |
use std::collections::HashMap; | |
use std::fs::File; | |
use std::io; | |
use ::fluent_bundle::{FluentBundle, FluentResource, FluentValue}; | |
use fluent_locale::{negotiate_languages, NegotiationStrategy}; | |
use handlebars::{ | |
Context, Handlebars, Helper, JsonRender, Output, RenderContext, RenderError, | |
}; | |
use rocket::fairing::AdHoc; | |
use rocket_contrib::templates::Template; | |
use lazy_static::lazy_static; | |
//use rocket_contrib::templates::handlebars::HelperResult; | |
struct RocketConfiguration { | |
l10n_path: String, | |
} | |
//t for t-ranslate | |
fn t( | |
h: &Helper<'_, '_>, | |
_: &Handlebars, | |
_: &Context, | |
_: &mut RenderContext<'_>, | |
out: &mut dyn Output, | |
) -> Result<(), RenderError> { | |
let id = h.param(0).ok_or(RenderError::new("A translation key is required, but was not provided."))?.value().render(); | |
let mut params = HashMap::new(); | |
for i in 1..256 { | |
match h.param(i) { | |
None => break, | |
Some(v) => { | |
let r = v.value().render(); | |
let split = r.split("="); | |
let splitted: Vec<&str> = split.take(2).collect(); | |
if let Some(s) = splitted.get(1) { | |
params.insert(splitted[0].to_string(), s.to_string()); | |
} else { | |
params.insert(splitted[0].to_string(), "".to_string()); | |
} | |
} | |
} | |
} | |
let mut map = HashMap::new(); | |
let translation_parameters = if params.is_empty() { | |
None | |
} else { | |
for (key, value) in ¶ms { | |
map.insert(key.as_str(), FluentValue::from(value.to_string())); | |
} | |
Some(&map) | |
}; | |
let translation = match fluent_bundle.1.format(&id, translation_parameters) { | |
Some(t) => { | |
t.0 | |
} | |
None => format!("[[missing {}]]", id), | |
}; | |
out.write(translation.as_ref())?; | |
Ok(()) | |
} | |
fn read_file(path: &str) -> Result<String, io::Error> { | |
use std::io::Read; | |
let mut f = File::open(path)?; | |
let mut s = String::new(); | |
f.read_to_string(&mut s)?; | |
Ok(s) | |
} | |
fn get_available_locales() -> Result<Vec<String>, io::Error> { | |
let mut locales = vec![]; | |
let res_dir = std::fs::read_dir("../var/instances/blog/translations/")?;//@fixme use Rocket.toml for loading | |
for entry in res_dir { | |
if let Ok(entry) = entry { | |
let path = entry.path(); | |
if path.is_dir() { | |
if let Some(name) = path.file_name() { | |
if let Some(name) = name.to_str() { | |
locales.push(String::from(name)); | |
} | |
} | |
} | |
} | |
} | |
return Ok(locales); | |
} | |
fn get_app_locales(requested: &[&str]) -> Result<Vec<String>, io::Error> { | |
let available = get_available_locales()?; | |
let resolved_locales = negotiate_languages( | |
requested, | |
&available, | |
Some("en-US"), | |
&NegotiationStrategy::Filtering, | |
); | |
return Ok(resolved_locales | |
.into_iter() | |
.map(|s| String::from(s)) | |
.collect::<Vec<String>>()); | |
} | |
static L10N_RESOURCES: &[&str] = &["base.ftl"]; | |
lazy_static! { //is there another way instead of lazy static? | |
static ref fluent_bundle: (Vec<String>, FluentBundle<'static>) = { | |
let locales = get_app_locales(&vec!["de-DE", "en-US"]).expect("Failed to retrieve available locales"); | |
let mut bundle = FluentBundle::new(&locales); | |
let mut resources: Vec<FluentResource> = vec![]; | |
for path in L10N_RESOURCES { | |
let full_path = format!( | |
"../var/instances/blog/translations/{locale}/{path}",//@fixme use Rocket.toml for loading | |
locale = locales[0], | |
path = path | |
); | |
let source = read_file(&full_path).unwrap(); | |
let resource = FluentResource::try_new(source).expect("Could not parse an FTL string."); | |
bundle.add_resource(&resource).expect("Failed to add FTL resources to the bundle."); | |
} | |
//I need both the locales and the fluent bundle later | |
(locales,bundle) | |
}; | |
} | |
fn main() { | |
rocket::ignite().mount("/", routes![]) | |
.attach(Template::custom(|engines| { | |
engines.handlebars.register_helper("t", Box::new(t)); | |
})) | |
.attach(AdHoc::on_attach("configuration", move |rocket| { | |
let configuration_file = File::open(&"../var/configuration/core.yaml").unwrap(); | |
let instance_name = rocket.config() | |
.get_str("instance_name") | |
.expect("instance_name not set") | |
.to_string(); | |
let l10n_path = rocket.config() | |
.get_str("l10n_path") | |
.expect("l10n_path not set") | |
.to_string().replace("{{instance}}", &instance_name); | |
Ok(rocket.manage( | |
RocketConfiguration { l10n_path } | |
)) | |
})) | |
.launch(); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment