1use serde::{Deserialize, Serialize};
3use std::collections::HashMap;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
6pub enum Language {
7 English,
8 Italian,
9 French,
10 German,
11 Spanish,
12}
13
14impl Language {
15 pub fn all() -> Vec<Language> {
16 vec![
17 Language::English,
18 Language::Italian,
19 Language::French,
20 Language::German,
21 Language::Spanish,
22 ]
23 }
24
25 pub fn name(&self) -> &'static str {
26 match self {
27 Language::English => "English",
28 Language::Italian => "Italiano",
29 Language::French => "Français",
30 Language::German => "Deutsch",
31 Language::Spanish => "Español",
32 }
33 }
34
35 pub fn code(&self) -> &'static str {
36 match self {
37 Language::English => "en",
38 Language::Italian => "it",
39 Language::French => "fr",
40 Language::German => "de",
41 Language::Spanish => "es",
42 }
43 }
44}
45
46impl Default for Language {
47 fn default() -> Self {
48 Language::English
49 }
50}
51
52#[derive(Debug, Clone)]
53pub struct Localizer {
54 current_language: Language,
55 strings: HashMap<Language, HashMap<String, String>>,
56}
57
58impl Default for Localizer {
59 fn default() -> Self {
60 Self::new()
61 }
62}
63
64impl Localizer {
65 pub fn new() -> Self {
66 let mut localizer = Self {
67 current_language: Language::default(),
68 strings: HashMap::new(),
69 };
70
71 localizer.load_english();
73 localizer.load_italian();
75 localizer.load_french();
77 localizer.load_german();
79 localizer.load_spanish();
81
82 localizer
83 }
84
85 fn load_english(&mut self) {
86 let mut en = HashMap::new();
87
88 en.insert("app_name".to_string(), "Epik Launcher".to_string());
90 en.insert("loading".to_string(), "Loading...".to_string());
91 en.insert("error".to_string(), "Error".to_string());
92 en.insert("success".to_string(), "Success".to_string());
93
94 en.insert("login".to_string(), "Login".to_string());
96 en.insert("logout".to_string(), "Logout".to_string());
97 en.insert("device_code".to_string(), "Device Code".to_string());
98
99 en.insert("library".to_string(), "Library".to_string());
101 en.insert("downloads".to_string(), "Downloads".to_string());
102 en.insert("import".to_string(), "Import".to_string());
103 en.insert("settings".to_string(), "Settings".to_string());
104
105 en.insert("install".to_string(), "Install".to_string());
107 en.insert("launch".to_string(), "Launch".to_string());
108 en.insert("uninstall".to_string(), "Uninstall".to_string());
109 en.insert("verify".to_string(), "Verify".to_string());
110 en.insert("repair".to_string(), "Repair".to_string());
111 en.insert("cancel".to_string(), "Cancel".to_string());
112
113 en.insert(
115 "no_downloads".to_string(),
116 "No active downloads".to_string(),
117 );
118 en.insert("download_speed".to_string(), "Speed".to_string());
119 en.insert("files".to_string(), "Files".to_string());
120
121 en.insert(
123 "general_settings".to_string(),
124 "General Settings".to_string(),
125 );
126 en.insert(
127 "download_settings".to_string(),
128 "Download Settings".to_string(),
129 );
130 en.insert(
131 "wine_settings".to_string(),
132 "Wine/Proton Settings".to_string(),
133 );
134 en.insert(
135 "advanced_settings".to_string(),
136 "Advanced Settings".to_string(),
137 );
138 en.insert("save".to_string(), "Save".to_string());
139 en.insert(
140 "reset_defaults".to_string(),
141 "Reset to Defaults".to_string(),
142 );
143
144 en.insert("import_game".to_string(), "Import Game".to_string());
146 en.insert("no_games_found".to_string(), "No games found".to_string());
147 en.insert(
148 "library_empty".to_string(),
149 "Your library is empty or not yet loaded".to_string(),
150 );
151 en.insert("get".to_string(), "Get".to_string());
152 en.insert("play".to_string(), "▶ Play".to_string());
153 en.insert("installing".to_string(), "⏳ Installing...".to_string());
154 en.insert("installed".to_string(), "Installed".to_string());
155 en.insert("not_installed".to_string(), "Not installed".to_string());
156 en.insert("view_details".to_string(), "View details".to_string());
157 en.insert("cloud_saves".to_string(), "Cloud Saves".to_string());
158 en.insert(
159 "update_available".to_string(),
160 "Update available".to_string(),
161 );
162 en.insert("wine_prefix".to_string(), "Wine Prefix".to_string());
163 en.insert("select_wine".to_string(), "Select Wine".to_string());
164 en.insert("custom".to_string(), "Custom".to_string());
165
166 en.insert("close".to_string(), "Close".to_string());
168 en.insert(
169 "auto_update_games".to_string(),
170 "Auto-update games".to_string(),
171 );
172 en.insert(
173 "auto_update_desc".to_string(),
174 "Automatically check and download updates".to_string(),
175 );
176 en.insert("start_minimized".to_string(), "Start minimized".to_string());
177 en.insert(
178 "start_minimized_desc".to_string(),
179 "Start the launcher minimized to system tray".to_string(),
180 );
181 en.insert(
182 "close_to_tray".to_string(),
183 "Close to system tray".to_string(),
184 );
185 en.insert(
186 "close_to_tray_desc".to_string(),
187 "Minimize to tray instead of closing".to_string(),
188 );
189 en.insert("language".to_string(), "Language".to_string());
190 en.insert("theme".to_string(), "Theme".to_string());
191 en.insert(
192 "max_concurrent".to_string(),
193 "Max concurrent downloads".to_string(),
194 );
195 en.insert(
196 "download_threads".to_string(),
197 "Download threads per game".to_string(),
198 );
199 en.insert(
200 "download_threads_desc".to_string(),
201 "More threads = faster downloads but more CPU usage".to_string(),
202 );
203 en.insert(
204 "bandwidth_limit".to_string(),
205 "Enable bandwidth limiting".to_string(),
206 );
207 en.insert(
208 "max_speed".to_string(),
209 "Maximum download speed".to_string(),
210 );
211 en.insert("cdn_region".to_string(), "CDN Region".to_string());
212 en.insert(
213 "auto_detect_wine".to_string(),
214 "Auto-detect Wine/Proton".to_string(),
215 );
216 en.insert(
217 "auto_detect_wine_desc".to_string(),
218 "Automatically find Wine and Proton installations".to_string(),
219 );
220 en.insert(
221 "wine_prefix_per_game".to_string(),
222 "Separate Wine prefix per game".to_string(),
223 );
224 en.insert(
225 "wine_prefix_desc".to_string(),
226 "Each game gets its own Wine prefix (recommended)".to_string(),
227 );
228 en.insert("enable_dxvk".to_string(), "Enable DXVK".to_string());
229 en.insert(
230 "dxvk_desc".to_string(),
231 "Vulkan-based Direct3D implementation".to_string(),
232 );
233 en.insert("enable_esync".to_string(), "Enable Esync".to_string());
234 en.insert(
235 "esync_desc".to_string(),
236 "Improved synchronization for better performance".to_string(),
237 );
238 en.insert("log_level".to_string(), "Log Level".to_string());
239 en.insert(
240 "enable_telemetry".to_string(),
241 "Enable anonymous telemetry".to_string(),
242 );
243 en.insert(
244 "telemetry_desc".to_string(),
245 "Help improve Epik by sending anonymous usage data".to_string(),
246 );
247 en.insert("log_to_file".to_string(), "Write logs to file".to_string());
248 en.insert(
249 "log_to_file_desc".to_string(),
250 "Store launcher logs in data/logs/epik.log".to_string(),
251 );
252 en.insert("crash_reporting".to_string(), "Crash reporting".to_string());
253 en.insert(
254 "crash_reporting_desc".to_string(),
255 "Generate crash reports on unexpected errors".to_string(),
256 );
257 en.insert(
258 "privacy_mode".to_string(),
259 "Privacy mode (hide library)".to_string(),
260 );
261 en.insert(
262 "privacy_mode_desc".to_string(),
263 "Hide titles and covers when sharing your screen".to_string(),
264 );
265 en.insert("hidden_game_title".to_string(), "Hidden game".to_string());
266 en.insert("current_file".to_string(), "Current".to_string());
267
268 en.insert("statistics".to_string(), "Statistics".to_string());
270 en.insert("playtime".to_string(), "Playtime".to_string());
271 en.insert("total_playtime".to_string(), "Total Playtime".to_string());
272 en.insert("launches".to_string(), "Launches".to_string());
273 en.insert("last_played".to_string(), "Last Played".to_string());
274 en.insert("first_played".to_string(), "First Played".to_string());
275 en.insert("play_sessions".to_string(), "Play Sessions".to_string());
276 en.insert("hours".to_string(), "hours".to_string());
277 en.insert("minutes".to_string(), "minutes".to_string());
278 en.insert("never".to_string(), "Never".to_string());
279 en.insert("session_history".to_string(), "Session History".to_string());
280 en.insert("duration".to_string(), "Duration".to_string());
281 en.insert(
282 "no_stats".to_string(),
283 "No statistics available yet".to_string(),
284 );
285
286 en.insert("achievements".to_string(), "Achievements".to_string());
288 en.insert("unlocked".to_string(), "Unlocked".to_string());
289 en.insert("locked".to_string(), "Locked".to_string());
290 en.insert("completion".to_string(), "Completion".to_string());
291 en.insert(
292 "no_achievements".to_string(),
293 "No achievements data available".to_string(),
294 );
295
296 en.insert("description".to_string(), "Description".to_string());
298 en.insert("screenshots".to_string(), "Screenshots".to_string());
299 en.insert(
300 "no_description".to_string(),
301 "Description not available yet".to_string(),
302 );
303 en.insert(
304 "no_screenshots".to_string(),
305 "Screenshots not available".to_string(),
306 );
307 en.insert(
308 "system_requirements".to_string(),
309 "System Requirements".to_string(),
310 );
311 en.insert(
312 "no_requirements".to_string(),
313 "System requirements not available".to_string(),
314 );
315 en.insert("version".to_string(), "Version".to_string());
316 en.insert("developer".to_string(), "Developer".to_string());
317 en.insert("publisher".to_string(), "Publisher".to_string());
318 en.insert("release_date".to_string(), "Release Date".to_string());
319
320 self.strings.insert(Language::English, en);
321 }
322
323 fn load_italian(&mut self) {
324 let mut it = HashMap::new();
325
326 it.insert("app_name".to_string(), "Epik Launcher".to_string());
328 it.insert("loading".to_string(), "Caricamento...".to_string());
329 it.insert("error".to_string(), "Errore".to_string());
330 it.insert("success".to_string(), "Successo".to_string());
331
332 it.insert("login".to_string(), "Accedi".to_string());
334 it.insert("logout".to_string(), "Esci".to_string());
335 it.insert("device_code".to_string(), "Codice Dispositivo".to_string());
336
337 it.insert("library".to_string(), "Libreria".to_string());
339 it.insert("downloads".to_string(), "Download".to_string());
340 it.insert("import".to_string(), "Importa".to_string());
341 it.insert("settings".to_string(), "Impostazioni".to_string());
342
343 it.insert("install".to_string(), "Installa".to_string());
345 it.insert("launch".to_string(), "Avvia".to_string());
346 it.insert("uninstall".to_string(), "Disinstalla".to_string());
347 it.insert("verify".to_string(), "Verifica".to_string());
348 it.insert("repair".to_string(), "Ripara".to_string());
349 it.insert("cancel".to_string(), "Annulla".to_string());
350
351 it.insert(
353 "no_downloads".to_string(),
354 "Nessun download attivo".to_string(),
355 );
356 it.insert("download_speed".to_string(), "Velocità".to_string());
357 it.insert("files".to_string(), "File".to_string());
358
359 it.insert(
361 "general_settings".to_string(),
362 "Impostazioni Generali".to_string(),
363 );
364 it.insert(
365 "download_settings".to_string(),
366 "Impostazioni Download".to_string(),
367 );
368 it.insert(
369 "wine_settings".to_string(),
370 "Impostazioni Wine/Proton".to_string(),
371 );
372 it.insert(
373 "advanced_settings".to_string(),
374 "Impostazioni Avanzate".to_string(),
375 );
376 it.insert("save".to_string(), "Salva".to_string());
377 it.insert(
378 "reset_defaults".to_string(),
379 "Ripristina Predefinite".to_string(),
380 );
381
382 it.insert("import_game".to_string(), "Importa Gioco".to_string());
384 it.insert(
385 "no_games_found".to_string(),
386 "Nessun gioco trovato".to_string(),
387 );
388 it.insert(
389 "library_empty".to_string(),
390 "La tua libreria è vuota o non ancora caricata".to_string(),
391 );
392 it.insert("get".to_string(), "Scarica".to_string());
393 it.insert("play".to_string(), "▶ Gioca".to_string());
394 it.insert(
395 "installing".to_string(),
396 "⏳ Installazione in corso...".to_string(),
397 );
398 it.insert("installed".to_string(), "Installato".to_string());
399 it.insert("not_installed".to_string(), "Non installato".to_string());
400 it.insert(
401 "view_details".to_string(),
402 "Visualizza dettagli".to_string(),
403 );
404 it.insert("cloud_saves".to_string(), "Cloud Saves".to_string());
405 it.insert(
406 "update_available".to_string(),
407 "Aggiornamento disponibile".to_string(),
408 );
409 it.insert("wine_prefix".to_string(), "Prefix Wine".to_string());
410 it.insert("select_wine".to_string(), "Seleziona Wine".to_string());
411 it.insert("custom".to_string(), "Personalizzato".to_string());
412
413 it.insert("close".to_string(), "Chiudi".to_string());
415 it.insert(
416 "auto_update_games".to_string(),
417 "Aggiorna automaticamente i giochi".to_string(),
418 );
419 it.insert(
420 "auto_update_desc".to_string(),
421 "Controlla e scarica automaticamente gli aggiornamenti".to_string(),
422 );
423 it.insert(
424 "start_minimized".to_string(),
425 "Avvia minimizzato".to_string(),
426 );
427 it.insert(
428 "start_minimized_desc".to_string(),
429 "Avvia il launcher minimizzato nella system tray".to_string(),
430 );
431 it.insert(
432 "close_to_tray".to_string(),
433 "Chiudi nella system tray".to_string(),
434 );
435 it.insert(
436 "close_to_tray_desc".to_string(),
437 "Minimizza nella tray invece di chiudere".to_string(),
438 );
439 it.insert("language".to_string(), "Lingua".to_string());
440 it.insert("theme".to_string(), "Tema".to_string());
441 it.insert(
442 "max_concurrent".to_string(),
443 "Download simultanei massimi".to_string(),
444 );
445 it.insert(
446 "download_threads".to_string(),
447 "Thread di download per gioco".to_string(),
448 );
449 it.insert(
450 "download_threads_desc".to_string(),
451 "Più thread = download più veloci ma maggiore uso CPU".to_string(),
452 );
453 it.insert(
454 "bandwidth_limit".to_string(),
455 "Abilita limitazione banda".to_string(),
456 );
457 it.insert(
458 "max_speed".to_string(),
459 "Velocità massima di download".to_string(),
460 );
461 it.insert("cdn_region".to_string(), "Regione CDN".to_string());
462 it.insert(
463 "auto_detect_wine".to_string(),
464 "Rileva automaticamente Wine/Proton".to_string(),
465 );
466 it.insert(
467 "auto_detect_wine_desc".to_string(),
468 "Trova automaticamente le installazioni di Wine e Proton".to_string(),
469 );
470 it.insert(
471 "wine_prefix_per_game".to_string(),
472 "Prefix Wine separato per gioco".to_string(),
473 );
474 it.insert(
475 "wine_prefix_desc".to_string(),
476 "Ogni gioco ha il proprio prefix Wine (consigliato)".to_string(),
477 );
478 it.insert("enable_dxvk".to_string(), "Abilita DXVK".to_string());
479 it.insert(
480 "dxvk_desc".to_string(),
481 "Implementazione Direct3D basata su Vulkan".to_string(),
482 );
483 it.insert("enable_esync".to_string(), "Abilita Esync".to_string());
484 it.insert(
485 "esync_desc".to_string(),
486 "Sincronizzazione migliorata per prestazioni migliori".to_string(),
487 );
488 it.insert("log_level".to_string(), "Livello Log".to_string());
489 it.insert(
490 "enable_telemetry".to_string(),
491 "Abilita telemetria anonima".to_string(),
492 );
493 it.insert(
494 "telemetry_desc".to_string(),
495 "Aiuta a migliorare Epik inviando dati anonimi di utilizzo".to_string(),
496 );
497 it.insert("log_to_file".to_string(), "Scrivi log su file".to_string());
498 it.insert(
499 "log_to_file_desc".to_string(),
500 "Salva i log in data/logs/epik.log".to_string(),
501 );
502 it.insert("crash_reporting".to_string(), "Crash reporting".to_string());
503 it.insert(
504 "crash_reporting_desc".to_string(),
505 "Genera report in caso di errori imprevisti".to_string(),
506 );
507 it.insert(
508 "privacy_mode".to_string(),
509 "Modalità privacy (nascondi libreria)".to_string(),
510 );
511 it.insert(
512 "privacy_mode_desc".to_string(),
513 "Nasconde titoli e cover quando condividi lo schermo".to_string(),
514 );
515 it.insert(
516 "hidden_game_title".to_string(),
517 "Gioco nascosto".to_string(),
518 );
519 it.insert("current_file".to_string(), "Corrente".to_string());
520
521 it.insert("statistics".to_string(), "Statistiche".to_string());
523 it.insert("playtime".to_string(), "Tempo di gioco".to_string());
524 it.insert("total_playtime".to_string(), "Tempo Totale".to_string());
525 it.insert("launches".to_string(), "Avvii".to_string());
526 it.insert("last_played".to_string(), "Ultima Partita".to_string());
527 it.insert("first_played".to_string(), "Prima Partita".to_string());
528 it.insert("play_sessions".to_string(), "Sessioni di Gioco".to_string());
529 it.insert("hours".to_string(), "ore".to_string());
530 it.insert("minutes".to_string(), "minuti".to_string());
531 it.insert("never".to_string(), "Mai".to_string());
532 it.insert(
533 "session_history".to_string(),
534 "Storico Sessioni".to_string(),
535 );
536 it.insert("duration".to_string(), "Durata".to_string());
537 it.insert(
538 "no_stats".to_string(),
539 "Nessuna statistica disponibile".to_string(),
540 );
541
542 it.insert("achievements".to_string(), "Obiettivi".to_string());
544 it.insert("unlocked".to_string(), "Sbloccato".to_string());
545 it.insert("locked".to_string(), "Bloccato".to_string());
546 it.insert("completion".to_string(), "Completamento".to_string());
547 it.insert(
548 "no_achievements".to_string(),
549 "Nessun obiettivo disponibile".to_string(),
550 );
551
552 it.insert("description".to_string(), "Descrizione".to_string());
554 it.insert("screenshots".to_string(), "Screenshot".to_string());
555 it.insert(
556 "no_description".to_string(),
557 "Descrizione non disponibile".to_string(),
558 );
559 it.insert(
560 "no_screenshots".to_string(),
561 "Screenshot non disponibili".to_string(),
562 );
563 it.insert(
564 "system_requirements".to_string(),
565 "Requisiti di Sistema".to_string(),
566 );
567 it.insert(
568 "no_requirements".to_string(),
569 "Requisiti di sistema non disponibili".to_string(),
570 );
571 it.insert("version".to_string(), "Versione".to_string());
572 it.insert("developer".to_string(), "Sviluppatore".to_string());
573 it.insert("publisher".to_string(), "Editore".to_string());
574 it.insert("release_date".to_string(), "Data di Rilascio".to_string());
575
576 self.strings.insert(Language::Italian, it);
577 }
578
579 fn load_french(&mut self) {
580 let mut fr = HashMap::new();
581 fr.insert("app_name".to_string(), "Epik Launcher".to_string());
582 fr.insert("loading".to_string(), "Chargement...".to_string());
583 fr.insert("error".to_string(), "Erreur".to_string());
584 fr.insert("success".to_string(), "Succès".to_string());
585 fr.insert("login".to_string(), "Connexion".to_string());
586 fr.insert("logout".to_string(), "Déconnexion".to_string());
587 fr.insert("library".to_string(), "Bibliothèque".to_string());
588 fr.insert("downloads".to_string(), "Téléchargements".to_string());
589 fr.insert("import".to_string(), "Importer".to_string());
590 fr.insert("settings".to_string(), "Paramètres".to_string());
591 fr.insert("install".to_string(), "Installer".to_string());
592 fr.insert("launch".to_string(), "Lancer".to_string());
593 fr.insert("uninstall".to_string(), "Désinstaller".to_string());
594 fr.insert("cancel".to_string(), "Annuler".to_string());
595 fr.insert("play".to_string(), "▶ Jouer".to_string());
596 fr.insert("installing".to_string(), "⏳ Installation...".to_string());
597 fr.insert("installed".to_string(), "Installé".to_string());
598 fr.insert("language".to_string(), "Langue".to_string());
599 fr.insert("statistics".to_string(), "Statistiques".to_string());
600 fr.insert("playtime".to_string(), "Temps de Jeu".to_string());
601 fr.insert("total_playtime".to_string(), "Temps Total".to_string());
602 fr.insert("launches".to_string(), "Lancements".to_string());
603 fr.insert("last_played".to_string(), "Dernière Partie".to_string());
604 fr.insert("achievements".to_string(), "Succès".to_string());
605 fr.insert("unlocked".to_string(), "Déverrouillé".to_string());
606 fr.insert("locked".to_string(), "Verrouillé".to_string());
607 fr.insert("description".to_string(), "Description".to_string());
608 fr.insert("version".to_string(), "Version".to_string());
609 fr.insert("developer".to_string(), "Développeur".to_string());
610 fr.insert("publisher".to_string(), "Éditeur".to_string());
611 fr.insert(
612 "log_to_file".to_string(),
613 "Écrire les logs sur fichier".to_string(),
614 );
615 fr.insert(
616 "log_to_file_desc".to_string(),
617 "Enregistrer les logs dans data/logs/epik.log".to_string(),
618 );
619 fr.insert(
620 "crash_reporting".to_string(),
621 "Rapports de crash".to_string(),
622 );
623 fr.insert(
624 "crash_reporting_desc".to_string(),
625 "Générer un rapport en cas d'erreur imprévue".to_string(),
626 );
627 fr.insert(
628 "privacy_mode".to_string(),
629 "Mode confidentialité (masquer la bibliothèque)".to_string(),
630 );
631 fr.insert(
632 "privacy_mode_desc".to_string(),
633 "Masque titres et couvertures lors du partage d'écran".to_string(),
634 );
635 fr.insert("hidden_game_title".to_string(), "Jeu masqué".to_string());
636 self.strings.insert(Language::French, fr);
637 }
638
639 fn load_german(&mut self) {
640 let mut de = HashMap::new();
641 de.insert("app_name".to_string(), "Epik Launcher".to_string());
642 de.insert("loading".to_string(), "Wird geladen...".to_string());
643 de.insert("error".to_string(), "Fehler".to_string());
644 de.insert("success".to_string(), "Erfolg".to_string());
645 de.insert("login".to_string(), "Anmelden".to_string());
646 de.insert("logout".to_string(), "Abmelden".to_string());
647 de.insert("library".to_string(), "Bibliothek".to_string());
648 de.insert("downloads".to_string(), "Downloads".to_string());
649 de.insert("import".to_string(), "Importieren".to_string());
650 de.insert("settings".to_string(), "Einstellungen".to_string());
651 de.insert("install".to_string(), "Installieren".to_string());
652 de.insert("launch".to_string(), "Starten".to_string());
653 de.insert("uninstall".to_string(), "Deinstallieren".to_string());
654 de.insert("cancel".to_string(), "Abbrechen".to_string());
655 de.insert("play".to_string(), "▶ Spielen".to_string());
656 de.insert(
657 "installing".to_string(),
658 "⏳ Installation läuft...".to_string(),
659 );
660 de.insert("installed".to_string(), "Installiert".to_string());
661 de.insert("language".to_string(), "Sprache".to_string());
662 de.insert("statistics".to_string(), "Statistiken".to_string());
663 de.insert("playtime".to_string(), "Spielzeit".to_string());
664 de.insert("total_playtime".to_string(), "Gesamtspielzeit".to_string());
665 de.insert("launches".to_string(), "Starts".to_string());
666 de.insert("last_played".to_string(), "Zuletzt gespielt".to_string());
667 de.insert("achievements".to_string(), "Erfolge".to_string());
668 de.insert("unlocked".to_string(), "Freigeschaltet".to_string());
669 de.insert("locked".to_string(), "Gesperrt".to_string());
670 de.insert("description".to_string(), "Beschreibung".to_string());
671 de.insert("version".to_string(), "Version".to_string());
672 de.insert("developer".to_string(), "Entwickler".to_string());
673 de.insert("publisher".to_string(), "Herausgeber".to_string());
674 de.insert(
675 "log_to_file".to_string(),
676 "Logs in Datei schreiben".to_string(),
677 );
678 de.insert(
679 "log_to_file_desc".to_string(),
680 "Logs in data/logs/epik.log speichern".to_string(),
681 );
682 de.insert("crash_reporting".to_string(), "Crash-Reporting".to_string());
683 de.insert(
684 "crash_reporting_desc".to_string(),
685 "Erzeuge Bericht bei unerwarteten Fehlern".to_string(),
686 );
687 de.insert(
688 "privacy_mode".to_string(),
689 "Privatsphäre-Modus (Bibliothek ausblenden)".to_string(),
690 );
691 de.insert(
692 "privacy_mode_desc".to_string(),
693 "Blendet Titel und Cover beim Bildschirmteilen aus".to_string(),
694 );
695 de.insert(
696 "hidden_game_title".to_string(),
697 "Verstecktes Spiel".to_string(),
698 );
699 self.strings.insert(Language::German, de);
700 }
701
702 fn load_spanish(&mut self) {
703 let mut es = HashMap::new();
704 es.insert("app_name".to_string(), "Epik Launcher".to_string());
705 es.insert("loading".to_string(), "Cargando...".to_string());
706 es.insert("error".to_string(), "Error".to_string());
707 es.insert("success".to_string(), "Éxito".to_string());
708 es.insert("login".to_string(), "Iniciar Sesión".to_string());
709 es.insert("logout".to_string(), "Cerrar Sesión".to_string());
710 es.insert("library".to_string(), "Biblioteca".to_string());
711 es.insert("downloads".to_string(), "Descargas".to_string());
712 es.insert("import".to_string(), "Importar".to_string());
713 es.insert("settings".to_string(), "Configuración".to_string());
714 es.insert("install".to_string(), "Instalar".to_string());
715 es.insert("launch".to_string(), "Iniciar".to_string());
716 es.insert("uninstall".to_string(), "Desinstalar".to_string());
717 es.insert("cancel".to_string(), "Cancelar".to_string());
718 es.insert("play".to_string(), "▶ Jugar".to_string());
719 es.insert("installing".to_string(), "⏳ Instalando...".to_string());
720 es.insert("installed".to_string(), "Instalado".to_string());
721 es.insert("language".to_string(), "Idioma".to_string());
722 es.insert("statistics".to_string(), "Estadísticas".to_string());
723 es.insert("playtime".to_string(), "Tiempo de Juego".to_string());
724 es.insert("total_playtime".to_string(), "Tiempo Total".to_string());
725 es.insert("launches".to_string(), "Inicios".to_string());
726 es.insert("last_played".to_string(), "Última Partida".to_string());
727 es.insert("achievements".to_string(), "Logros".to_string());
728 es.insert("unlocked".to_string(), "Desbloqueado".to_string());
729 es.insert("locked".to_string(), "Bloqueado".to_string());
730 es.insert("description".to_string(), "Descripción".to_string());
731 es.insert("version".to_string(), "Versión".to_string());
732 es.insert("developer".to_string(), "Desarrollador".to_string());
733 es.insert("publisher".to_string(), "Editorial".to_string());
734 es.insert(
735 "log_to_file".to_string(),
736 "Guardar registros en archivo".to_string(),
737 );
738 es.insert(
739 "log_to_file_desc".to_string(),
740 "Guardar registros en data/logs/epik.log".to_string(),
741 );
742 es.insert(
743 "crash_reporting".to_string(),
744 "Reporte de fallos".to_string(),
745 );
746 es.insert(
747 "crash_reporting_desc".to_string(),
748 "Generar un informe ante errores inesperados".to_string(),
749 );
750 es.insert(
751 "privacy_mode".to_string(),
752 "Modo privacidad (ocultar biblioteca)".to_string(),
753 );
754 es.insert(
755 "privacy_mode_desc".to_string(),
756 "Oculta títulos y portadas al compartir pantalla".to_string(),
757 );
758 es.insert("hidden_game_title".to_string(), "Juego oculto".to_string());
759 self.strings.insert(Language::Spanish, es);
760 }
761
762 pub fn set_language(&mut self, language: Language) {
763 self.current_language = language;
764 }
765
766 pub fn get_language(&self) -> Language {
767 self.current_language
768 }
769
770 pub fn t(&self, key: &str) -> String {
771 self.strings
772 .get(&self.current_language)
773 .and_then(|lang_map| lang_map.get(key))
774 .cloned()
775 .unwrap_or_else(|| {
776 self.strings
778 .get(&Language::English)
779 .and_then(|lang_map| lang_map.get(key))
780 .cloned()
781 .unwrap_or_else(|| key.to_string())
782 })
783 }
784}
785
786#[cfg(test)]
787mod tests {
788 use super::*;
789
790 #[test]
791 fn test_english_translation() {
792 let localizer = Localizer::new();
793 assert_eq!(localizer.t("library"), "Library");
794 assert_eq!(localizer.t("install"), "Install");
795 }
796
797 #[test]
798 fn test_italian_translation() {
799 let mut localizer = Localizer::new();
800 localizer.set_language(Language::Italian);
801 assert_eq!(localizer.t("library"), "Libreria");
802 assert_eq!(localizer.t("install"), "Installa");
803 }
804
805 #[test]
806 fn test_french_translation() {
807 let mut localizer = Localizer::new();
808 localizer.set_language(Language::French);
809 assert_eq!(localizer.t("library"), "Bibliothèque");
810 assert_eq!(localizer.t("launch"), "Lancer");
811 }
812
813 #[test]
814 fn test_german_translation() {
815 let mut localizer = Localizer::new();
816 localizer.set_language(Language::German);
817 assert_eq!(localizer.t("library"), "Bibliothek");
818 assert_eq!(localizer.t("launch"), "Starten");
819 }
820
821 #[test]
822 fn test_spanish_translation() {
823 let mut localizer = Localizer::new();
824 localizer.set_language(Language::Spanish);
825 assert_eq!(localizer.t("library"), "Biblioteca");
826 assert_eq!(localizer.t("launch"), "Iniciar");
827 }
828
829 #[test]
830 fn test_all_languages() {
831 let languages = Language::all();
832 assert_eq!(languages.len(), 5);
833 assert!(languages.contains(&Language::English));
834 assert!(languages.contains(&Language::Italian));
835 assert!(languages.contains(&Language::French));
836 assert!(languages.contains(&Language::German));
837 assert!(languages.contains(&Language::Spanish));
838 }
839
840 #[test]
841 fn test_language_codes() {
842 assert_eq!(Language::English.code(), "en");
843 assert_eq!(Language::Italian.code(), "it");
844 assert_eq!(Language::French.code(), "fr");
845 assert_eq!(Language::German.code(), "de");
846 assert_eq!(Language::Spanish.code(), "es");
847 }
848
849 #[test]
850 fn test_language_names() {
851 assert_eq!(Language::English.name(), "English");
852 assert_eq!(Language::Italian.name(), "Italiano");
853 assert_eq!(Language::French.name(), "Français");
854 assert_eq!(Language::German.name(), "Deutsch");
855 assert_eq!(Language::Spanish.name(), "Español");
856 }
857
858 #[test]
859 fn test_fallback_to_english() {
860 let mut localizer = Localizer::new();
861 localizer.set_language(Language::Italian);
862 assert_eq!(localizer.t("nonexistent_key"), "nonexistent_key");
864 }
865}