Skip to main content

aurora_locale/
lib.rs

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}