hex_patch/app/settings/
locale.rs1use serde::{Deserialize, Serialize};
2
3macro_rules! EnumValues {(
4 $(#[$attr:meta])*
5 $pub:vis enum $enum_name:ident {
6 $(
7 $(#[$field_attr:meta])*
8 $field_name:ident,
9 )*
10 }) => {
11 impl $enum_name {
12 $pub const VALUES: &'static [$enum_name] = &[
13 $(
14 $enum_name::$field_name,
15 )*
16 ];
17 }
18 }
19}
20macro_rules! LocaleCode {(
21 $(#[$attr:meta])*
22 $pub:vis enum $enum_name:ident {
23 $(
24 $(#[$field_attr:meta])*
25 $field_name:ident,
26 )*
27 }) => {
28 impl $enum_name {
29 $pub const fn code(&self) -> &'static str {
30 match self {
31 $(
32 $enum_name::$field_name => const_str::replace!(stringify!($field_name),"_", "-"),
33 )*
34 }
35 }
36 }
37 }
38}
39
40#[allow(non_camel_case_types)]
41#[non_exhaustive]
42#[derive(EnumValues!)]
43#[derive(LocaleCode!)]
44#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
45pub enum Locale {
46 #[default]
47 auto, en,
49 #[serde(rename = "it-IT")]
50 it_IT,
51 #[serde(rename = "fr-FR")]
52 fr_FR,
53 #[serde(rename = "es-ES")]
54 es_ES,
55 #[serde(rename = "de-DE")]
56 de_DE,
57 #[serde(rename = "ja-JP")]
58 ja_JP,
59 #[serde(rename = "zh-CN")]
60 zh_CN,
61 #[serde(rename = "zh-TW")]
62 zh_TW,
63 #[serde(rename = "zh-HK")]
64 zh_HK,
65 #[serde(rename = "tr-TR")]
66 tr_TR,
67}
68
69impl Locale {
70 pub const fn name(&self) -> &'static str {
71 match self {
72 Locale::auto => "Auto",
73 Locale::en => "English",
74 Locale::it_IT => "Italiano (Italia)",
75 Locale::fr_FR => "Français (France)",
76 Locale::es_ES => "Español (España)",
77 Locale::de_DE => "Deutsch (Deutschland)",
78 Locale::ja_JP => "日本語 (日本)",
79 Locale::zh_CN => "中文 (中国)",
80 Locale::zh_TW => "中文 (台灣)",
81 Locale::zh_HK => "中文 (香港)",
82 Locale::tr_TR => "Türkçe (Türkiye)",
83 }
84 }
85 pub fn language(&self) -> &'static str {
86 self.code().split('-').next().unwrap()
87 }
88 pub fn match_locale(&self, locale: &str) -> Option<Locale> {
89 for l in &Locale::VALUES[1..] {
92 if locale.starts_with(l.code()) {
93 return Some(*l);
94 }
95 }
96 for l in &Locale::VALUES[1..] {
98 if locale.starts_with(l.language()) {
99 return Some(*l);
100 }
101 }
102 None
103 }
104 pub fn apply(&self) {
105 match self {
106 Locale::auto => {
107 let locale = 'found: {
108 for locale in sys_locale::get_locales() {
109 if let Some(locale) = self.match_locale(&locale) {
110 break 'found locale;
111 }
112 }
113 Locale::en };
115 rust_i18n::set_locale(locale.code());
116 }
117 _ => {
118 rust_i18n::set_locale(self.code());
119 }
120 }
121 }
122}