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