1#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
29pub enum Language {
30 #[default]
32 English,
33 French,
35 Spanish,
37 German,
39 Italian,
41 PortugueseBR,
43 PortuguesePT,
45 ChineseSimplified,
47}
48
49impl Language {
50 #[must_use]
66 pub const fn to_locale(self) -> &'static str {
67 match self {
68 Self::English => "en",
69 Self::French => "fr",
70 Self::Spanish => "es",
71 Self::German => "de",
72 Self::Italian => "it",
73 Self::PortugueseBR => "pt-BR",
74 Self::PortuguesePT => "pt-PT",
75 Self::ChineseSimplified => "zh-CN",
76 }
77 }
78}
79
80#[derive(Debug, Clone, Copy, Default)]
94pub struct Translations {
95 language: Language,
96}
97
98impl Translations {
99 #[must_use]
112 pub fn new(language: Language) -> Self {
113 rust_i18n::set_locale(language.to_locale());
114 Self { language }
115 }
116
117 #[must_use]
128 pub const fn language(&self) -> Language {
129 self.language
130 }
131
132 pub fn set_language(&mut self, language: Language) {
146 self.language = language;
147 rust_i18n::set_locale(language.to_locale());
148 }
149
150 #[must_use]
164 pub fn search_placeholder(&self) -> String {
165 rust_i18n::t!("search.placeholder", locale = self.language.to_locale())
166 .into_owned()
167 }
168
169 #[must_use]
180 pub fn replace_placeholder(&self) -> String {
181 rust_i18n::t!("replace.placeholder", locale = self.language.to_locale())
182 .into_owned()
183 }
184
185 #[must_use]
196 pub fn case_sensitive_label(&self) -> String {
197 rust_i18n::t!(
198 "settings.case_sensitive_label",
199 locale = self.language.to_locale()
200 )
201 .into_owned()
202 }
203
204 #[must_use]
215 pub fn previous_match_tooltip(&self) -> String {
216 rust_i18n::t!(
217 "search.previous_match_tooltip",
218 locale = self.language.to_locale()
219 )
220 .into_owned()
221 }
222
223 #[must_use]
234 pub fn next_match_tooltip(&self) -> String {
235 rust_i18n::t!(
236 "search.next_match_tooltip",
237 locale = self.language.to_locale()
238 )
239 .into_owned()
240 }
241
242 #[must_use]
253 pub fn close_search_tooltip(&self) -> String {
254 rust_i18n::t!(
255 "search.close_tooltip",
256 locale = self.language.to_locale()
257 )
258 .into_owned()
259 }
260
261 #[must_use]
272 pub fn replace_current_tooltip(&self) -> String {
273 rust_i18n::t!(
274 "replace.current_tooltip",
275 locale = self.language.to_locale()
276 )
277 .into_owned()
278 }
279
280 #[must_use]
291 pub fn replace_all_tooltip(&self) -> String {
292 rust_i18n::t!("replace.all_tooltip", locale = self.language.to_locale())
293 .into_owned()
294 }
295}
296
297#[cfg(test)]
298mod tests {
299 use super::*;
300
301 #[test]
302 fn test_default_language() {
303 let translations = Translations::default();
304 assert_eq!(translations.language(), Language::English);
305 }
306
307 #[test]
308 fn test_new_with_language() {
309 let translations = Translations::new(Language::French);
310 assert_eq!(translations.language(), Language::French);
311 }
312
313 #[test]
314 fn test_set_language() {
315 let mut translations = Translations::new(Language::English);
316 translations.set_language(Language::Spanish);
317 assert_eq!(translations.language(), Language::Spanish);
318 }
319
320 #[test]
321 fn test_english_translations() {
322 let t = Translations::new(Language::English);
323 assert_eq!(t.search_placeholder(), "Search...");
324 assert_eq!(t.replace_placeholder(), "Replace...");
325 assert_eq!(t.case_sensitive_label(), "Case sensitive");
326 assert_eq!(t.previous_match_tooltip(), "Previous match (Shift+F3)");
327 assert_eq!(t.next_match_tooltip(), "Next match (F3 / Enter)");
328 assert_eq!(t.close_search_tooltip(), "Close search dialog (Esc)");
329 assert_eq!(t.replace_current_tooltip(), "Replace current match");
330 assert_eq!(t.replace_all_tooltip(), "Replace all matches");
331 }
332
333 #[test]
334 fn test_french_translations() {
335 let t = Translations::new(Language::French);
336 assert_eq!(t.search_placeholder(), "Rechercher...");
337 assert_eq!(t.replace_placeholder(), "Remplacer...");
338 assert_eq!(t.case_sensitive_label(), "Sensible à la casse");
339 assert_eq!(t.previous_match_tooltip(), "Résultat précédent (Maj+F3)");
340 assert_eq!(t.next_match_tooltip(), "Résultat suivant (F3 / Entrée)");
341 assert_eq!(t.close_search_tooltip(), "Fermer la recherche (Échap)");
342 assert_eq!(
343 t.replace_current_tooltip(),
344 "Remplacer l'occurrence actuelle"
345 );
346 assert_eq!(t.replace_all_tooltip(), "Tout remplacer");
347 }
348
349 #[test]
350 fn test_spanish_translations() {
351 let t = Translations::new(Language::Spanish);
352 assert_eq!(t.search_placeholder(), "Buscar...");
353 assert_eq!(t.replace_placeholder(), "Reemplazar...");
354 assert_eq!(t.case_sensitive_label(), "Distinguir mayúsculas");
355 assert_eq!(
356 t.previous_match_tooltip(),
357 "Coincidencia anterior (Mayús+F3)"
358 );
359 assert_eq!(
360 t.next_match_tooltip(),
361 "Siguiente coincidencia (F3 / Enter)"
362 );
363 assert_eq!(t.close_search_tooltip(), "Cerrar búsqueda (Esc)");
364 assert_eq!(
365 t.replace_current_tooltip(),
366 "Reemplazar coincidencia actual"
367 );
368 assert_eq!(t.replace_all_tooltip(), "Reemplazar todo");
369 }
370
371 #[test]
372 fn test_german_translations() {
373 let t = Translations::new(Language::German);
374 assert_eq!(t.search_placeholder(), "Suchen...");
375 assert_eq!(t.replace_placeholder(), "Ersetzen...");
376 assert_eq!(t.case_sensitive_label(), "Groß-/Kleinschreibung");
377 assert_eq!(
378 t.previous_match_tooltip(),
379 "Vorheriger Treffer (Umschalt+F3)"
380 );
381 assert_eq!(t.next_match_tooltip(), "Nächster Treffer (F3 / Enter)");
382 assert_eq!(t.close_search_tooltip(), "Suchdialog schließen (Esc)");
383 assert_eq!(t.replace_current_tooltip(), "Aktuellen Treffer ersetzen");
384 assert_eq!(t.replace_all_tooltip(), "Alle ersetzen");
385 }
386
387 #[test]
388 fn test_italian_translations() {
389 let t = Translations::new(Language::Italian);
390 assert_eq!(t.search_placeholder(), "Cerca...");
391 assert_eq!(t.replace_placeholder(), "Sostituisci...");
392 assert_eq!(t.case_sensitive_label(), "Distingui maiuscole");
393 assert_eq!(
394 t.previous_match_tooltip(),
395 "Risultato precedente (Maiusc+F3)"
396 );
397 assert_eq!(t.next_match_tooltip(), "Risultato successivo (F3 / Invio)");
398 assert_eq!(
399 t.close_search_tooltip(),
400 "Chiudi finestra di ricerca (Esc)"
401 );
402 assert_eq!(
403 t.replace_current_tooltip(),
404 "Sostituisci risultato corrente"
405 );
406 assert_eq!(t.replace_all_tooltip(), "Sostituisci tutto");
407 }
408
409 #[test]
410 fn test_portuguese_br_translations() {
411 let t = Translations::new(Language::PortugueseBR);
412 assert_eq!(t.search_placeholder(), "Pesquisar...");
413 assert_eq!(t.replace_placeholder(), "Substituir...");
414 assert_eq!(t.case_sensitive_label(), "Diferenciar maiúsculas");
415 assert_eq!(
416 t.previous_match_tooltip(),
417 "Correspondência anterior (Shift+F3)"
418 );
419 assert_eq!(
420 t.next_match_tooltip(),
421 "Próxima correspondência (F3 / Enter)"
422 );
423 assert_eq!(
424 t.close_search_tooltip(),
425 "Fechar diálogo de pesquisa (Esc)"
426 );
427 assert_eq!(
428 t.replace_current_tooltip(),
429 "Substituir correspondência atual"
430 );
431 assert_eq!(t.replace_all_tooltip(), "Substituir tudo");
432 }
433
434 #[test]
435 fn test_portuguese_pt_translations() {
436 let t = Translations::new(Language::PortuguesePT);
437 assert_eq!(t.search_placeholder(), "Pesquisar...");
438 assert_eq!(t.replace_placeholder(), "Substituir...");
439 assert_eq!(t.case_sensitive_label(), "Diferenciar maiúsculas");
440 assert_eq!(
441 t.previous_match_tooltip(),
442 "Correspondência anterior (Shift+F3)"
443 );
444 assert_eq!(
445 t.next_match_tooltip(),
446 "Próxima correspondência (F3 / Enter)"
447 );
448 assert_eq!(
449 t.close_search_tooltip(),
450 "Fechar diálogo de pesquisa (Esc)"
451 );
452 assert_eq!(
453 t.replace_current_tooltip(),
454 "Substituir correspondência actual"
455 );
456 assert_eq!(t.replace_all_tooltip(), "Substituir tudo");
457 }
458
459 #[test]
460 fn test_language_switching() {
461 let mut t = Translations::new(Language::English);
462 assert_eq!(t.search_placeholder(), "Search...");
463
464 t.set_language(Language::French);
465 assert_eq!(t.search_placeholder(), "Rechercher...");
466
467 t.set_language(Language::Spanish);
468 assert_eq!(t.search_placeholder(), "Buscar...");
469
470 t.set_language(Language::German);
471 assert_eq!(t.search_placeholder(), "Suchen...");
472
473 t.set_language(Language::Italian);
474 assert_eq!(t.search_placeholder(), "Cerca...");
475
476 t.set_language(Language::PortugueseBR);
477 assert_eq!(t.search_placeholder(), "Pesquisar...");
478
479 t.set_language(Language::PortuguesePT);
480 assert_eq!(t.search_placeholder(), "Pesquisar...");
481
482 t.set_language(Language::ChineseSimplified);
483 assert_eq!(t.search_placeholder(), "搜索...");
484 }
485}