Move translation mechanism to excternal crates

master
Tait Hoyem 1 year ago
parent 0c3bcf5072
commit 4a1f48b3bc

215
Cargo.lock generated

@ -31,6 +31,15 @@ dependencies = [
"libc",
]
[[package]]
name = "ansi_term"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
dependencies = [
"winapi",
]
[[package]]
name = "anyhow"
version = "1.0.70"
@ -125,6 +134,17 @@ dependencies = [
"num-traits",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi 0.1.19",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.1.0"
@ -300,6 +320,21 @@ dependencies = [
"phf_codegen",
]
[[package]]
name = "clap"
version = "2.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
dependencies = [
"ansi_term",
"atty",
"bitflags",
"strsim",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]]
name = "codespan-reporting"
version = "0.11.1"
@ -310,6 +345,12 @@ dependencies = [
"unicode-width",
]
[[package]]
name = "convert_case"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
[[package]]
name = "core-foundation-sys"
version = "0.8.3"
@ -413,6 +454,19 @@ dependencies = [
"syn 2.0.11",
]
[[package]]
name = "derive_more"
version = "0.99.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
dependencies = [
"convert_case",
"proc-macro2",
"quote",
"rustc_version",
"syn 1.0.109",
]
[[package]]
name = "deunicode"
version = "0.4.3"
@ -604,6 +658,12 @@ dependencies = [
"wasi 0.11.0+wasi-snapshot-preview1",
]
[[package]]
name = "glob"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "globset"
version = "0.4.10"
@ -661,6 +721,15 @@ dependencies = [
"unicode-segmentation",
]
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "hermit-abi"
version = "0.2.6"
@ -793,7 +862,10 @@ dependencies = [
"axum",
"axum-macros",
"chrono",
"derive_more",
"once_cell",
"ormx",
"rust-i18n",
"serde",
"serde-xml-rs",
"serde_plain",
@ -904,6 +976,12 @@ dependencies = [
"cc",
]
[[package]]
name = "linked-hash-map"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "lock_api"
version = "0.4.9"
@ -1013,7 +1091,7 @@ version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
dependencies = [
"hermit-abi",
"hermit-abi 0.2.6",
"libc",
]
@ -1339,6 +1417,84 @@ dependencies = [
"winapi",
]
[[package]]
name = "rust-i18n"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3dcb86b090a450cb642b6a465f0e9a3d4be26bdb9d8795a2a49fb02601b370f"
dependencies = [
"anyhow",
"clap",
"glob",
"itertools",
"once_cell",
"quote",
"regex",
"rust-i18n-extract",
"rust-i18n-macro",
"serde",
"serde_derive",
"toml",
]
[[package]]
name = "rust-i18n-extract"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec44568e2cdf4bfb7a62381bbc6fcdf0a27c60cd503dfa12c59e6c17cf3177fa"
dependencies = [
"anyhow",
"ignore",
"proc-macro2",
"quote",
"regex",
"rust-i18n-support",
"serde",
"serde_json",
"serde_yaml",
"syn 1.0.109",
]
[[package]]
name = "rust-i18n-macro"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e7e3e8f27d472822c5cf092a22631ebc667d9f8dc89dfc50ef4e87f4ebdf92f"
dependencies = [
"glob",
"once_cell",
"proc-macro2",
"quote",
"rust-i18n-support",
"serde",
"serde_json",
"serde_yaml",
"syn 1.0.109",
]
[[package]]
name = "rust-i18n-support"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e6bbf2d058c3558bef952564ceb9afcb19631cde22b47dc44f436e62ecfb916"
dependencies = [
"glob",
"once_cell",
"proc-macro2",
"serde",
"serde_json",
"serde_yaml",
]
[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver",
]
[[package]]
name = "rustls"
version = "0.19.1"
@ -1395,6 +1551,12 @@ dependencies = [
"untrusted",
]
[[package]]
name = "semver"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
[[package]]
name = "serde"
version = "1.0.159"
@ -1489,6 +1651,18 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_yaml"
version = "0.8.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b"
dependencies = [
"indexmap",
"ryu",
"serde",
"yaml-rust",
]
[[package]]
name = "sha-1"
version = "0.10.1"
@ -1687,6 +1861,12 @@ dependencies = [
"unicode-normalization",
]
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "strum"
version = "0.24.1"
@ -1775,6 +1955,15 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
]
[[package]]
name = "thiserror"
version = "1.0.40"
@ -1893,6 +2082,15 @@ dependencies = [
"tokio-stream",
]
[[package]]
name = "toml"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
dependencies = [
"serde",
]
[[package]]
name = "tower"
version = "0.4.13"
@ -2084,6 +2282,12 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "version_check"
version = "0.9.4"
@ -2383,3 +2587,12 @@ name = "xml-rs"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]

@ -22,6 +22,21 @@ sqlx = { version = "0.5", features = ["macros", "postgres", "runtime-tokio-rustl
ormx = { version = "0.10.0", features = ["postgres"] }
serde-xml-rs = "0.6.0"
strum = { version = "0.24.1", features = ["derive"] }
rust-i18n = "1.1.4"
once_cell = "1.17.1"
derive_more = "0.99.17"
[dev-dependencies]
tokio-test = "0.4.2"
[package.metadata.i18n]
# The available locales for your application, default: ["en"].
available-loCAles = ["en-CA", "fr-CA"]
# The default locale, default: "en".
default-locale = "en-CA"
# Path for your translations YAML file, default: "locales".
# This config for let `cargo i18n` command line tool know where to find your translations.
# You must keep this path is same as the path you pass to `rust_i18n::i18n!` method.
load-path = "translations"

@ -1,13 +1,38 @@
mod db;
mod filters;
mod model;
mod translations;
mod views;
use crate::model::{Division, Game, GamePlayer, League, Player, Shot, Team};
use translations::SupportedLanguage;
use crate::model::{Division, Game, GamePlayer, League, Player, Shot, Team, Language};
use serde::{Serialize, Deserialize};
use derive_more::Display;
#[derive(Serialize, Deserialize, Clone, Copy, Debug, Display)]
pub enum SupportedLanguage {
#[serde(rename="en-ca")]
#[display(fmt="en-ca")]
English,
#[serde(rename="fr-ca")]
#[display(fmt="fr-ca")]
French,
}
/*
impl std::fmt::Display for SupportedLanguage {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::English => write!(fmt, "en-ca"),
Self::French => write!(fmt, "fr-ca"),
}
}
}
*/
use views::{GoalDetails, PlayerStats, ShotDetails, TeamStats, IihfStatsI64};
use rust_i18n::t;
rust_i18n::i18n!("translations");
use askama::Template;
use axum::{
extract::{Path, State},
@ -29,6 +54,12 @@ struct HelloTemplate<'a> {
years: i32,
}
#[derive(Template)]
#[template(path = "language_list.html")]
struct LanguageListTemplate {
pub languages: Vec<Language>,
}
#[derive(Template)]
#[template(path = "partials/box_score_table.html")]
struct BoxScoreTemplate {
@ -117,13 +148,14 @@ pub struct ServerState {
#[tokio::main]
async fn main() {
println!("{}", t!("hello", locale="fr"));
println!("{:?}", available_locales());
let pool = db::connect().await;
let xml_en = translations::en_lang();
let xml_fr = translations::fr_lang();
let state = ServerState {
db_pool: Arc::new(pool),
};
let router = Router::new()
.route("/", get(language_list))
.route("/:lang/", get(league_html))
.route("/:lang/shots/", get(shots_all))
.route("/:lang/test/", get(test_template))
@ -140,6 +172,18 @@ async fn main() {
.unwrap();
}
async fn language_list(
State(server_config): State<ServerState>,
) -> impl IntoResponse {
let languages = Language::all(&*server_config.db_pool)
.await
.unwrap();
let lang_list_tmpl = LanguageListTemplate {
languages
};
(StatusCode::OK, lang_list_tmpl)
}
async fn player_from_name(
State(server_config): State<ServerState>,
Path((lang, name)): Path<(SupportedLanguage, String)>,

@ -14,6 +14,14 @@ macro_rules! impl_table_name {
}
}
#[derive(FromRow, Serialize, Deserialize, Debug, ormx::Table)]
#[ormx(table = "supported_languages", id = id, insertable, deletable)]
pub struct Language {
pub id: i32,
pub native_name: String,
pub short_name: String,
}
#[derive(FromRow, Serialize, Deserialize, Debug, ormx::Table)]
#[ormx(table = "leagues", id = id, insertable, deletable)]
pub struct League {

@ -1,79 +0,0 @@
use serde::{Serialize, Deserialize};
use strum::{
EnumIter,
IntoEnumIterator,
};
#[derive(Serialize, Deserialize, Debug, PartialEq, Copy, Clone)]
pub enum SupportedLanguage {
#[serde(rename = "en")]
English,
#[serde(rename = "fr")]
French,
}
impl std::fmt::Display for SupportedLanguage {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let output = match self {
Self::English => "en",
Self::French => "fr",
};
write!(f, "{}", output)
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, EnumIter)]
#[serde(rename_all = "camelCase")]
pub enum TranslatedKey {
UrlGame,
UrlDivision,
UrlLeague,
IbihfLeagues,
Goals,
Assists,
Period,
}
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct TranslatedString {
#[serde(rename = "name")]
pub key: TranslatedKey,
#[serde(rename = "$value")]
pub value: String,
}
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct LanguageStrings {
#[serde(rename = "$value")]
pub kvs: Vec<TranslatedString>,
}
/// Verify that all keys are present for translations.
pub fn verify_resources(ls: &LanguageStrings) -> bool {
for key in TranslatedKey::iter() {
let mut is_available = false;
for strs in &ls.kvs {
if strs.key == key {
is_available = true;
}
}
if !is_available {
return false;
}
}
true
}
macro_rules! add_language {
($func_name:ident, $file_name:expr) => {
pub fn $func_name() -> LanguageStrings {
let strings = serde_xml_rs::from_str(include_str!($file_name)).unwrap();
if !verify_resources(&strings) {
panic!("The language XML for {} is not correct.", $file_name);
}
strings
}
}
}
add_language!(en_lang, "../translations/en.xml");
add_language!(fr_lang, "../translations/fr.xml");
Loading…
Cancel
Save