Skip to content

Instantly share code, notes, and snippets.

@rust-play
Created July 3, 2019 18:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rust-play/b2ea5e7df918c9562aeeaf118f88de0e to your computer and use it in GitHub Desktop.
Save rust-play/b2ea5e7df918c9562aeeaf118f88de0e to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
#![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 &params {
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