1use std::collections::HashMap;
2
3pub use actix_cloud_codegen::i18n;
4
5#[macro_export]
22macro_rules! t {
23 ($l:expr, $key:expr) => {
24 $l.translate(&$l.default, $key)
25 };
26
27 ($l:expr, $key:expr, $($var_name:tt = $var_val:expr),+) => {
28 {
29 let mut message = $l.translate(&$l.default, $key);
30 $(
31 message = message.replace(concat!("%{", stringify!($var_name), "}"), $var_val);
32 )+
33 message
34 }
35 };
36
37 ($l:expr, $key:expr, $locale:expr) => {
38 $l.translate($locale, $key)
39 };
40
41 ($l:expr, $key:expr, $locale:expr, $($var_name:tt = $var_val:expr),+) => {
42 {
43 let mut message = $l.translate($locale, $key);
44 $(
45 message = message.replace(concat!("%{", stringify!($var_name), "}"), $var_val);
46 )+
47 message
48 }
49 };
50}
51
52#[macro_export]
61macro_rules! map {
62 {$($key:expr => $value:expr),+} => {{
63 let mut m = std::collections::HashMap::new();
64 $(
65 m.insert($key, $value);
66 )+
67 m
68 }};
69}
70
71#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
72#[derive(Debug)]
73pub struct Locale {
74 pub locale: HashMap<String, String>,
75 pub default: String,
76}
77
78impl Locale {
79 pub fn new<S: Into<String>>(default: S) -> Self {
80 Self {
81 locale: HashMap::new(),
82 default: default.into(),
83 }
84 }
85
86 pub fn add_locale<S: Into<String>>(mut self, l: HashMap<S, S>) -> Self {
88 self.locale
89 .extend(l.into_iter().map(|(a, b)| (a.into(), b.into())));
90 self
91 }
92
93 pub fn translate<S1: AsRef<str>, S2: AsRef<str>>(&self, locale: S1, key: S2) -> String {
97 let locale_key = format!("{}.{}", locale.as_ref(), key.as_ref());
98 self.locale.get(locale_key.as_str()).map_or_else(
99 || {
100 if locale.as_ref() == self.default {
101 key.as_ref().to_owned()
102 } else {
103 self.translate(&self.default, key)
104 }
105 },
106 ToString::to_string,
107 )
108 }
109}