Add i18n to state
This commit is contained in:
parent
bcd5c65a12
commit
e8593b5f5a
|
@ -308,6 +308,7 @@ dependencies = [
|
|||
"bcrypt",
|
||||
"diesel",
|
||||
"dotenv",
|
||||
"fluent-bundle",
|
||||
"r2d2",
|
||||
"regex",
|
||||
"rocket",
|
||||
|
@ -316,6 +317,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"unic-langid",
|
||||
"validator",
|
||||
]
|
||||
|
||||
|
@ -331,6 +333,36 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluent-bundle"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a79916560098f0a57215a489e37b7fc83088949eab7f7977dcc329b254d50c17"
|
||||
dependencies = [
|
||||
"fluent-langneg",
|
||||
"fluent-syntax",
|
||||
"intl-memoizer",
|
||||
"intl_pluralrules",
|
||||
"rental",
|
||||
"smallvec",
|
||||
"unic-langid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluent-langneg"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c4ad0989667548f06ccd0e306ed56b61bd4d35458d54df5ec7587c0e8ed5e94"
|
||||
dependencies = [
|
||||
"unic-langid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluent-syntax"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9389354f858e38f37d9a249133611a1fcaec469f44773b04ddbd82f4f08d49eb"
|
||||
|
||||
[[package]]
|
||||
name = "fsevent"
|
||||
version = "0.4.0"
|
||||
|
@ -366,6 +398,15 @@ version = "0.3.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||
|
||||
[[package]]
|
||||
name = "fxhash"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.3"
|
||||
|
@ -555,6 +596,26 @@ dependencies = [
|
|||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "intl-memoizer"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a0ed58ba6089d49f8a9a7d5e16fc9b9e2019cdf40ef270f3d465fa244d9630b"
|
||||
dependencies = [
|
||||
"type-map",
|
||||
"unic-langid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "intl_pluralrules"
|
||||
version = "7.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c271cdb1f12a9feb3a017619c3ee681f971f270f6757341d6abe1f9f7a98bc3"
|
||||
dependencies = [
|
||||
"tinystr",
|
||||
"unic-langid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iovec"
|
||||
version = "0.1.4"
|
||||
|
@ -1022,6 +1083,27 @@ version = "0.6.20"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cab7a364d15cde1e505267766a2d3c4e22a843e1a601f0fa7564c0f82ced11c"
|
||||
|
||||
[[package]]
|
||||
name = "rental"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8545debe98b2b139fb04cad8618b530e9b07c152d99a5de83c860b877d67847f"
|
||||
dependencies = [
|
||||
"rental-impl",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rental-impl"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "475e68978dc5b743f2f40d8e0a8fdc83f1c5e78cbf4b8fa5e74e73beebc340de"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.44",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rocket"
|
||||
version = "0.4.5"
|
||||
|
@ -1214,6 +1296,12 @@ version = "1.4.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "state"
|
||||
version = "0.4.1"
|
||||
|
@ -1274,6 +1362,12 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinystr"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29738eedb4388d9ea620eeab9384884fc3f06f586a2eddb56bedc5885126c7c1"
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "0.3.4"
|
||||
|
@ -1295,6 +1389,15 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
|
||||
|
||||
[[package]]
|
||||
name = "type-map"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d2741b1474c327d95c1f1e3b0a2c3977c8e128409c572a33af2914e7d636717"
|
||||
dependencies = [
|
||||
"fxhash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typeable"
|
||||
version = "0.1.2"
|
||||
|
@ -1313,6 +1416,24 @@ version = "0.1.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
||||
|
||||
[[package]]
|
||||
name = "unic-langid"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73328fcd730a030bdb19ddf23e192187a6b01cd98be6d3140622a89129459ce5"
|
||||
dependencies = [
|
||||
"unic-langid-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unic-langid-impl"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a4a8eeaf0494862c1404c95ec2f4c33a2acff5076f64314b465e3ddae1b934d"
|
||||
dependencies = [
|
||||
"tinystr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "1.4.2"
|
||||
|
|
|
@ -15,12 +15,14 @@ publish = true
|
|||
[dependencies]
|
||||
bcrypt = "0.8.2"
|
||||
dotenv = "0.15.0"
|
||||
fluent-bundle = "0.13.1"
|
||||
r2d2 = "0.8.9"
|
||||
regex = "1.4.1"
|
||||
rocket_csrf = { path = "/home/kotovalexarian/repos/github/kotovalexarian/rocket_csrf" }
|
||||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
serde_json = "1.0"
|
||||
unic-langid = "0.9.0"
|
||||
|
||||
[dependencies.diesel]
|
||||
version = "1.4.5"
|
||||
|
|
|
@ -128,6 +128,19 @@ impl Config {
|
|||
Ok(result_str.to_string())
|
||||
}
|
||||
|
||||
pub fn locales_path(&self) -> Result<String, ()> {
|
||||
let mut result_path_buf = std::path::PathBuf::new();
|
||||
result_path_buf.push(self.root.to_string());
|
||||
result_path_buf.push("locales");
|
||||
|
||||
let result_str = match result_path_buf.to_str() {
|
||||
None => return Err(()),
|
||||
Some(value) => value,
|
||||
};
|
||||
|
||||
Ok(result_str.to_string())
|
||||
}
|
||||
|
||||
pub fn use_env_for_root(&mut self) {
|
||||
self.root = match std::env::var("ROOT") {
|
||||
Err(_) => return,
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use fluent_bundle::FluentResource;
|
||||
use fluent_bundle::concurrent::FluentBundle;
|
||||
use unic_langid::LanguageIdentifier;
|
||||
|
||||
pub struct I18n(HashMap<String, FluentBundle<FluentResource>>);
|
||||
|
||||
impl I18n {
|
||||
pub fn new(path: &str, locales: &[&str]) -> Result<Self, ()> {
|
||||
let lang_ids: Vec<Result<LanguageIdentifier, _>> =
|
||||
locales.iter().map(|locale| {
|
||||
locale.parse::<LanguageIdentifier>()
|
||||
}).collect();
|
||||
|
||||
if let Some(_) = lang_ids.iter().find(|lang_id| lang_id.is_err()) {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
let lang_ids: Vec<&LanguageIdentifier> =
|
||||
lang_ids.iter().map(|lang_id| lang_id.as_ref().unwrap()).collect();
|
||||
|
||||
let mut hash_map = HashMap::new();
|
||||
|
||||
for lang_id in lang_ids {
|
||||
let locale = lang_id.to_string();
|
||||
|
||||
let mut path_buf = std::path::PathBuf::from(path);
|
||||
path_buf.push(&locale);
|
||||
path_buf.set_extension("ftl");
|
||||
|
||||
let data = match std::fs::read_to_string(path_buf) {
|
||||
Ok(data) => data,
|
||||
Err(_) => return Err(()),
|
||||
};
|
||||
|
||||
let resource = match FluentResource::try_new(data) {
|
||||
Ok(resource) => resource,
|
||||
Err(_) => return Err(()),
|
||||
};
|
||||
|
||||
let mut bundle = FluentBundle::default();
|
||||
|
||||
if let Err(_) = bundle.add_resource(resource) {
|
||||
return Err(());
|
||||
};
|
||||
|
||||
hash_map.insert(locale, bundle);
|
||||
}
|
||||
|
||||
Ok(Self(hash_map))
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
mod config;
|
||||
mod database;
|
||||
mod forms;
|
||||
mod i18n;
|
||||
mod models;
|
||||
mod responses;
|
||||
mod routes;
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
use crate::states;
|
||||
use crate::views;
|
||||
|
||||
use crate::i18n::I18n;
|
||||
use crate::responses::CommonResponse;
|
||||
|
||||
use rocket::State;
|
||||
use rocket_contrib::templates::Template;
|
||||
use rocket_csrf::CsrfToken;
|
||||
|
||||
#[get("/")]
|
||||
pub fn index(
|
||||
_i18n: State<I18n>,
|
||||
csrf_token: CsrfToken,
|
||||
current_user: states::MaybeCurrentUser,
|
||||
) -> Result<Template, CommonResponse> {
|
||||
|
|
|
@ -4,8 +4,10 @@ use crate::views;
|
|||
use crate::models;
|
||||
use crate::forms;
|
||||
|
||||
use crate::i18n::I18n;
|
||||
use crate::responses::CommonResponse;
|
||||
|
||||
use rocket::State;
|
||||
use rocket::http::{Cookie, Cookies};
|
||||
use rocket::response::Redirect;
|
||||
use rocket::request::Form;
|
||||
|
@ -14,6 +16,7 @@ use rocket_csrf::CsrfToken;
|
|||
|
||||
#[get("/sign_in")]
|
||||
pub fn new(
|
||||
_i18n: State<I18n>,
|
||||
csrf_token: CsrfToken,
|
||||
current_user: states::MaybeCurrentUser,
|
||||
) -> Result<Template, CommonResponse> {
|
||||
|
@ -40,6 +43,7 @@ pub fn new(
|
|||
|
||||
#[post("/sign_in", data = "<form>")]
|
||||
pub fn create(
|
||||
_i18n: State<I18n>,
|
||||
csrf_token: CsrfToken,
|
||||
db_conn: database::DbConn,
|
||||
current_user: states::MaybeCurrentUser,
|
||||
|
@ -76,6 +80,7 @@ pub fn create(
|
|||
|
||||
#[delete("/sign_out", data = "<form>")]
|
||||
pub fn delete(
|
||||
_i18n: State<I18n>,
|
||||
csrf_token: CsrfToken,
|
||||
current_user: states::MaybeCurrentUser,
|
||||
form: Form<forms::UserSignOut>,
|
||||
|
|
|
@ -4,8 +4,10 @@ use crate::views;
|
|||
use crate::models;
|
||||
use crate::forms;
|
||||
|
||||
use crate::i18n::I18n;
|
||||
use crate::responses::CommonResponse;
|
||||
|
||||
use rocket::State;
|
||||
use rocket::http::{Cookie, Cookies};
|
||||
use rocket::response::Redirect;
|
||||
use rocket::request::Form;
|
||||
|
@ -14,6 +16,7 @@ use rocket_csrf::CsrfToken;
|
|||
|
||||
#[get("/sign_up")]
|
||||
pub fn new(
|
||||
_i18n: State<I18n>,
|
||||
csrf_token: CsrfToken,
|
||||
current_user: states::MaybeCurrentUser,
|
||||
) -> Result<Template, CommonResponse> {
|
||||
|
@ -40,6 +43,7 @@ pub fn new(
|
|||
|
||||
#[post("/sign_up", data = "<form>")]
|
||||
pub fn create(
|
||||
_i18n: State<I18n>,
|
||||
csrf_token: CsrfToken,
|
||||
db_conn: database::DbConn,
|
||||
current_user: states::MaybeCurrentUser,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::config;
|
||||
use crate::database;
|
||||
use crate::i18n::I18n;
|
||||
use crate::routes;
|
||||
|
||||
use rocket_contrib::serve::{Options as ServeOptions, StaticFiles};
|
||||
|
@ -8,9 +9,13 @@ use rocket_contrib::templates::Template;
|
|||
pub fn rocket(config: &config::Config) -> Result<rocket::Rocket, ()> {
|
||||
let rocket_config = config.to_rocket_config()?;
|
||||
|
||||
let public_path = config.public_path()?;
|
||||
let public_path = config.public_path()?;
|
||||
let locales_path = config.locales_path()?;
|
||||
|
||||
let i18n = I18n::new(&locales_path, &["en", "ru"])?;
|
||||
|
||||
let result = rocket::custom(rocket_config)
|
||||
.manage(i18n)
|
||||
.manage(database::create_db_pool(config))
|
||||
.attach(rocket_csrf::Fairing::new())
|
||||
.attach(Template::fairing())
|
||||
|
|
Reference in New Issue