1use std::env;
2
3#[derive(Debug, Clone, Copy, PartialEq)]
4pub enum Language {
5 Russian,
6 English,
7}
8
9impl Language {
10 pub fn is_ru(self) -> bool { self == Language::Russian }
11}
12
13#[derive(Debug, Clone)]
14pub struct Localizer {
15 pub lang: Language,
16}
17
18impl Localizer {
19 pub fn detect() -> Self {
20 let lang = detect_locale();
21 Self { lang }
22 }
23
24 pub fn from_override(s: &str) -> Self {
25 let s = s.to_lowercase();
26 let lang = if s == "ru" || s.starts_with("ru_") {
27 Language::Russian
28 } else {
29 Language::English
30 };
31 Self { lang }
32 }
33
34 pub fn t<'a>(&self, ru: &'a str, en: &'a str) -> &'a str {
35 match self.lang {
36 Language::Russian => ru,
37 Language::English => en,
38 }
39 }
40
41 pub fn msg(&self, key: &str) -> String {
42 messages(self.lang, key)
43 }
44
45 pub fn fmt(&self, ru: &str, en: &str, args: &[(&str, &str)]) -> String {
46 let template = self.t(ru, en);
47 let mut result = template.to_string();
48 for (k, v) in args {
49 result = result.replace(&format!("{{{k}}}"), v);
50 }
51 result
52 }
53}
54
55fn detect_locale() -> Language {
56 for var in &["LC_ALL", "LC_MESSAGES", "LANG"] {
57 if let Ok(val) = env::var(var) {
58 let val = val.to_lowercase();
59 if val == "ru" || val.starts_with("ru_") {
60 return Language::Russian;
61 }
62 }
63 }
64 Language::English
65}
66
67fn messages(lang: Language, key: &str) -> String {
68 match lang {
69 Language::Russian => ru_messages(key),
70 Language::English => en_messages(key),
71 }
72}
73
74fn ru_messages(key: &str) -> String {
75 match key {
76 "welcome" => "Добро пожаловать в Aurora!".to_string(),
77 "goodbye" => "До свидания!".to_string(),
78 "searching" => "Поиск...".to_string(),
79 "found_files" => "Найдено файлов: {count}".to_string(),
80 "indexing" => "Индексация...".to_string(),
81 "index_updated" => "Индекс обновлён: {count} файлов".to_string(),
82 "converting" => "Конвертация...".to_string(),
83 "processing" => "Обработка...".to_string(),
84 "error" => "Ошибка: {msg}".to_string(),
85 "loading" => "Загрузка...".to_string(),
86 "done" => "Готово!".to_string(),
87 "elapsed" => "Прошло: {time}с".to_string(),
88 "no_results" => "Ничего не найдено".to_string(),
89 "joke_break" => "А пока — шутка:".to_string(),
90 "thinking" => "Думаю...".to_string(),
91 "cancel_hint" => "Нажми Ctrl+C для отмены".to_string(),
92 "config_loaded" => "Конфиг загружен".to_string(),
93 "session_resumed" => "Сессия восстановлена".to_string(),
94 "debug_analyzing" => "Анализирую проблему...".to_string(),
95 "debug_suggestion" => "Возможное решение: {suggestion}".to_string(),
96 _ => key.to_string(),
97 }
98}
99
100fn en_messages(key: &str) -> String {
101 match key {
102 "welcome" => "Welcome to Aurora!".to_string(),
103 "goodbye" => "Goodbye!".to_string(),
104 "searching" => "Searching...".to_string(),
105 "found_files" => "Files found: {count}".to_string(),
106 "indexing" => "Indexing...".to_string(),
107 "index_updated" => "Index updated: {count} files".to_string(),
108 "converting" => "Converting...".to_string(),
109 "processing" => "Processing...".to_string(),
110 "error" => "Error: {msg}".to_string(),
111 "loading" => "Loading...".to_string(),
112 "done" => "Done!".to_string(),
113 "elapsed" => "Elapsed: {time}s".to_string(),
114 "no_results" => "No results found".to_string(),
115 "joke_break" => "Meanwhile, a joke:".to_string(),
116 "thinking" => "Thinking...".to_string(),
117 "cancel_hint" => "Press Ctrl+C to cancel".to_string(),
118 "config_loaded" => "Config loaded".to_string(),
119 "session_resumed" => "Session resumed".to_string(),
120 "debug_analyzing" => "Analyzing the issue...".to_string(),
121 "debug_suggestion" => "Possible fix: {suggestion}".to_string(),
122 _ => key.to_string(),
123 }
124}
125
126#[cfg(test)]
127mod tests {
128 use super::*;
129
130 #[test]
131 fn test_detect_ru() {
132 let loc = Localizer::from_override("ru_RU.UTF-8");
133 assert_eq!(loc.lang, Language::Russian);
134 }
135
136 #[test]
137 fn test_detect_en() {
138 let loc = Localizer::from_override("en_US.UTF-8");
139 assert_eq!(loc.lang, Language::English);
140 }
141
142 #[test]
143 fn test_translate() {
144 let ru = Localizer::from_override("ru_RU");
145 let en = Localizer::from_override("en_US");
146 assert_eq!(ru.t("Search", "Поиск"), "Поиск");
147 assert_eq!(en.t("Search", "Поиск"), "Search");
148 }
149}