extern crate fluent;
extern crate fluent_locale;
use fluent::bundle::FluentBundle;
use fluent::types::FluentValue;
use fluent_locale::{negotiate_languages, NegotiationStrategy};
use std::collections::HashMap;
use std::env;
use std::fs;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::str::FromStr;
fn read_file(path: &str) -> Result<String, io::Error> {
let mut f = try!(File::open(path));
let mut s = String::new();
try!(f.read_to_string(&mut s));
Ok(s)
}
fn get_available_locales() -> Result<Vec<String>, io::Error> {
let mut locales = vec![];
let res_dir = fs::read_dir("./examples/resources/")?;
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] = &["simple.ftl"];
fn main() {
let args: Vec<String> = env::args().collect();
let requested = args
.get(2)
.map_or(vec!["en-US"], |arg| arg.split(",").collect());
let locales = get_app_locales(&requested).expect("Failed to retrieve available locales");
let mut bundle = FluentBundle::new(&locales);
for path in L10N_RESOURCES {
let full_path = format!(
"./examples/resources/{locale}/{path}",
locale = locales[0],
path = path
);
let res = read_file(&full_path).unwrap();
bundle.add_messages(&res).unwrap();
}
match args.get(1) {
Some(input) => {
match isize::from_str(&input) {
Ok(i) => {
let mut args = HashMap::new();
args.insert("input", FluentValue::from(i));
args.insert("value", FluentValue::from(collatz(i)));
println!("{}", bundle.format("response-msg", Some(&args)).unwrap().0);
}
Err(err) => {
let mut args = HashMap::new();
args.insert("input", FluentValue::from(input.to_string()));
args.insert("reason", FluentValue::from(err.to_string()));
println!(
"{}",
bundle
.format("input-parse-error-msg", Some(&args))
.unwrap()
.0
);
}
}
}
None => {
println!("{}", bundle.format("missing-arg-error", None).unwrap().0);
}
}
}
fn collatz(n: isize) -> isize {
match n {
1 => 0,
_ => match n % 2 {
0 => 1 + collatz(n / 2),
_ => 1 + collatz(n * 3 + 1),
},
}
}