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