完善i18n陕西按逻辑,增加宏处理

This commit is contained in:
李运家 2024-06-19 15:11:18 +08:00
parent ebf4c82f18
commit 9260049da0
12 changed files with 101 additions and 177 deletions

135
Cargo.lock generated
View File

@ -472,17 +472,6 @@ dependencies = [
"subtle", "subtle",
] ]
[[package]]
name = "displaydoc"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.52",
]
[[package]] [[package]]
name = "domain" name = "domain"
version = "0.1.0" version = "0.1.0"
@ -608,50 +597,6 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6"
[[package]]
name = "fluent"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb74634707bebd0ce645a981148e8fb8c7bccd4c33c652aeffd28bf2f96d555a"
dependencies = [
"fluent-bundle",
"unic-langid",
]
[[package]]
name = "fluent-bundle"
version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fe0a21ee80050c678013f82edf4b705fe2f26f1f9877593d13198612503f493"
dependencies = [
"fluent-langneg",
"fluent-syntax",
"intl-memoizer",
"intl_pluralrules",
"rustc-hash",
"self_cell 0.10.3",
"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.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a530c4694a6a8d528794ee9bbd8ba0122e779629ac908d15ad5a7ae7763a33d"
dependencies = [
"thiserror",
]
[[package]] [[package]]
name = "flume" name = "flume"
version = "0.11.0" version = "0.11.0"
@ -999,9 +944,8 @@ dependencies = [
name = "i18n" name = "i18n"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"fluent",
"lazy_static", "lazy_static",
"unic-langid", "tracing",
] ]
[[package]] [[package]]
@ -1053,25 +997,6 @@ dependencies = [
"hashbrown", "hashbrown",
] ]
[[package]]
name = "intl-memoizer"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe22e020fce238ae18a6d5d8c502ee76a52a6e880d99477657e6acc30ec57bda"
dependencies = [
"type-map",
"unic-langid",
]
[[package]]
name = "intl_pluralrules"
version = "7.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972"
dependencies = [
"unic-langid",
]
[[package]] [[package]]
name = "ipnet" name = "ipnet"
version = "2.9.0" version = "2.9.0"
@ -1160,6 +1085,7 @@ dependencies = [
"http", "http",
"http-body", "http-body",
"http-body-util", "http-body-util",
"i18n",
"jsonwebtoken", "jsonwebtoken",
"lazy_static", "lazy_static",
"moka", "moka",
@ -1825,12 +1751,6 @@ version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]] [[package]]
name = "rustc_version" name = "rustc_version"
version = "0.4.0" version = "0.4.0"
@ -1959,21 +1879,6 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "self_cell"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e14e4d63b804dc0c7ec4a1e52bcb63f02c7ac94476755aa579edac21e01f915d"
dependencies = [
"self_cell 1.0.4",
]
[[package]]
name = "self_cell"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a"
[[package]] [[package]]
name = "semver" name = "semver"
version = "1.0.22" version = "1.0.22"
@ -2542,15 +2447,6 @@ dependencies = [
"time-core", "time-core",
] ]
[[package]]
name = "tinystr"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
dependencies = [
"displaydoc",
]
[[package]] [[package]]
name = "tinyvec" name = "tinyvec"
version = "1.6.0" version = "1.6.0"
@ -2805,15 +2701,6 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "type-map"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "deb68604048ff8fa93347f02441e4487594adc20bb8a084f9e564d2b827a0a9f"
dependencies = [
"rustc-hash",
]
[[package]] [[package]]
name = "typenum" name = "typenum"
version = "1.17.0" version = "1.17.0"
@ -2831,24 +2718,6 @@ dependencies = [
"web-time", "web-time",
] ]
[[package]]
name = "unic-langid"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23dd9d1e72a73b25e07123a80776aae3e7b0ec461ef94f9151eed6ec88005a44"
dependencies = [
"unic-langid-impl",
]
[[package]]
name = "unic-langid-impl"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a5422c1f65949306c99240b81de9f3f15929f5a8bfe05bb44b034cc8bf593e5"
dependencies = [
"tinystr",
]
[[package]] [[package]]
name = "unicode-bidi" name = "unicode-bidi"
version = "0.3.15" version = "0.3.15"

View File

@ -42,6 +42,4 @@ futures-executor = "0.3"
error-stack = "0.4" error-stack = "0.4"
jsonwebtoken = "9.3.0" jsonwebtoken = "9.3.0"
lazy_static = "1.4.0" lazy_static = "1.4.0"
mimalloc = "0.1.42" mimalloc = "0.1.42"
fluent = "0.16.1"
unic-langid = "0.9.5"

View File

@ -20,5 +20,5 @@ pub async fn add_feedback(
pub async fn get_feedback_list_by_page( pub async fn get_feedback_list_by_page(
Query(page_params): Query<PageParams> Query(page_params): Query<PageParams>
) -> ResResult<ResData<Pageable<Feedback>>> { ) -> ResResult<ResData<Pageable<Feedback>>> {
service::feedback::get_feedback_list_by_page(page_params.page, page_params.page_size).await service::feedback::get_feedback_list_by_page(page_params.page.unwrap(), page_params.page_size.unwrap()).await
} }

View File

@ -26,9 +26,9 @@ pub(crate) fn init() -> Router {
post(controller::feedback::add_feedback) post(controller::feedback::add_feedback)
.get(controller::feedback::get_feedback_list_by_page), .get(controller::feedback::get_feedback_list_by_page),
) )
.layer(axum::middleware::from_fn( /* .layer(axum::middleware::from_fn(
library::middleware::req_ctx::authenticate_ctx, library::middleware::req_ctx::authenticate_ctx,
)); )) */;
Router::new() Router::new()
.nest("/", open) .nest("/", open)

View File

@ -1,7 +1,11 @@
use serde::Deserialize; use serde::Deserialize;
use validator::Validate;
#[derive(Deserialize)] #[derive(Deserialize, Validate)]
pub struct PageParams { pub struct PageParams {
pub page: i64, #[validate(required(message = "页码不能为空"), range(min = 1, message = "页码不能小于1"))]
pub page_size: i64, pub page: Option<i64>,
#[serde(rename = "pageSize")]
#[validate(required(message = "每页数量不能为空"), range(min = 1, message = "每页数量不能小于1"))]
pub page_size: Option<i64>,
} }

View File

@ -4,6 +4,5 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
fluent = { workspace = true } lazy_static = { workspace = true }
unic-langid = { workspace = true, feature = ["unic-langid-macros", "macros"]} tracing = { workspace = true }
lazy_static = { workspace = true }

View File

@ -1,3 +1,15 @@
pub const MESSAGE: &str = r#" use std::collections::HashMap;
hello = "hello {$name}"
"#; use lazy_static::lazy_static;
use crate::message_ids::HELLO;
pub const LANGUAGE_ID: &str = "en-US";
lazy_static! {
pub static ref MESSAGE: HashMap<&'static str, &'static str> = {
let mut map = HashMap::new();
map.insert(HELLO, "hello {}");
map
};
}

View File

@ -1,35 +1,61 @@
use std::{cell::RefCell, collections::HashMap, sync::{Arc, Mutex, OnceLock, RwLock}}; extern crate self as i18n;
use fluent::{FluentBundle, FluentResource}; use std::{collections::HashMap, sync::OnceLock};
use lazy_static::lazy_static;
pub mod message_ids;
pub mod en_us; pub mod en_us;
pub mod zh_cn; pub mod zh_cn;
// static I18N: OnceLock<HashMap<&str, Arc<FluentBundle<FluentResource>>>> = OnceLock::new(); static I18N: OnceLock<HashMap<&'static str, HashMap<&'static str, &'static str>>> = OnceLock::new();
lazy_static!{ fn init_i18n() -> HashMap<&'static str, HashMap<&'static str, &'static str>> {
pub static ref I18N_MAP: RwLock<HashMap<&static str, Arc<FluentBundle<FluentResource>>>> = { let mut i18n_map = HashMap::new();
init_i18n() i18n_map.insert(en_us::LANGUAGE_ID, en_us::MESSAGE.clone());
}; i18n_map.insert(zh_cn::LANGUAGE_ID, zh_cn::MESSAGE.clone());
i18n_map
} }
pub fn init_i18n() -> RwLock<HashMap<&'static str, Arc<FluentBundle<FluentResource>>>> { fn get_i18n() -> &'static HashMap<&'static str, HashMap<&'static str, &'static str>> {
// 英文资源初始化 I18N.get_or_init(init_i18n)
let langid_en_us = "en-US".parse().expect("初始化英文标识失败"); }
let en_us_res = FluentResource::try_new(en_us::MESSAGE.to_string()).expect("初始化英文资源失败");
let mut en_us_bundle = FluentBundle::new(vec![langid_en_us]);
en_us_bundle.add_resource(en_us_res).expect("添加英文资源失败");
// 简体中文资源初始化 pub fn lang(lang_id: &'static str, message_id: &'static str) -> &'static str {
let langid_zh_cn = "en-US".parse().expect("初始化简体中文标识失败"); get_i18n()
let zh_cn_res = FluentResource::try_new(en_us::MESSAGE.to_string()).expect("初始化简体中文资源失败"); .get(lang_id)
let mut zj_cn_bundle = FluentBundle::new(vec![langid_zh_cn]); .and_then(|map| map.get(message_id))
zj_cn_bundle.add_resource(zh_cn_res).expect("添加简体中文资源失败"); .unwrap_or_else(|| &"UNKNOWN")
}
let mut map = HashMap::new(); pub fn convert_message_with_params(message_template: &'static str, args: Vec<&str>) -> String {
map.insert("en-US", Arc::new(en_us_bundle)); if message_template.contains("{}") {
map.insert("zh-CN", Arc::new(zj_cn_bundle)); let message_split_array: Vec<&str> = message_template.split("{}").collect();
RwLock::new(map) // tracing::info!("message_template: {:?}, args: {:?}", message_split_array, args);
} let mut message = String::new();
for (index, message_ele) in message_split_array.iter().enumerate() {
message += message_ele;
if index < args.len() && index != message_split_array.len() - 1 {
message += args[index];
}
}
message
} else {
String::from(message_template)
}
}
#[macro_export]
macro_rules! message {
($lang_id:expr, $message_id:expr) => {
i18n::lang($lang_id, $message_id)
};
($lang_id:expr, $message_id:expr, $($arg:expr),*) => {
{
let message_template: &'static str = i18n::lang($lang_id, $message_id);
let mut args: Vec<&str> = vec![];
$(
args.push($arg);
)*
i18n::convert_message_with_params(message_template, args)
}
};
}

1
i18n/src/message_ids.rs Normal file
View File

@ -0,0 +1 @@
pub const HELLO: &str = "hello";

View File

@ -1,3 +1,15 @@
pub const MESSAGE: &str = r#" use std::collections::HashMap;
hello = "你好 {$name}"
"#; use lazy_static::lazy_static;
use crate::message_ids::HELLO;
pub const LANGUAGE_ID: &str = "zh_CN";
lazy_static! {
pub static ref MESSAGE: HashMap<&'static str, &'static str> = {
let mut map = HashMap::new();
map.insert(HELLO, "你好 {}");
map
};
}

View File

@ -29,4 +29,5 @@ validator = { workspace = true }
moka = { workspace = true, features = ["future", "logging"] } moka = { workspace = true, features = ["future", "logging"] }
lazy_static = { workspace = true } lazy_static = { workspace = true }
domain = { path = "../domain" } domain = { path = "../domain" }
i18n = { path = "../i18n" }

View File

@ -1,5 +1,6 @@
use domain::dto::feedback::FeedbackAdd; use domain::dto::feedback::FeedbackAdd;
use domain::entities::feedback::Feedback; use domain::entities::feedback::Feedback;
use i18n::message;
use library::db; use library::db;
use library::res::pageable::Pageable; use library::res::pageable::Pageable;
use library::res::response::{ResData, ResResult}; use library::res::response::{ResData, ResResult};
@ -12,6 +13,7 @@ pub async fn get_feedback_list_by_page(page: i64, page_size: i64) -> ResResult<R
return Ok(ResData::some(Pageable::<Feedback>::empty())); return Ok(ResData::some(Pageable::<Feedback>::empty()));
} }
let total = get_feedback_count().await; let total = get_feedback_count().await;
tracing::info!("你好: {}", message!("zh_CN", "hello", "明天", "结束"));
Ok(ResData::some(Pageable::new(feedback_list.unwrap(), total))) Ok(ResData::some(Pageable::new(feedback_list.unwrap(), total)))
} }