rush_sync_server/commands/lang/
persistence.rs

1// commands/lang/persistence.rs - TOML FILE OPERATIONEN
2
3use crate::core::prelude::*;
4use std::path::PathBuf;
5
6/// Verwaltet das Speichern/Laden von Language-Konfigurationen
7pub struct LanguagePersistence;
8
9impl LanguagePersistence {
10    /// Speichert Sprache in Config-Datei (von screen.rs übernommen)
11    pub async fn save_to_config(lang: &str) -> Result<()> {
12        let config_paths = crate::setup::setup_toml::get_config_paths();
13
14        for path in config_paths {
15            if path.exists() {
16                let content = tokio::fs::read_to_string(&path)
17                    .await
18                    .map_err(AppError::Io)?;
19
20                // ✅ INTELLIGENT: Regex für saubere Ersetzung
21                let updated_content = if content.contains("[language]") {
22                    // Bestehende current = Zeile ersetzen
23                    content
24                        .lines()
25                        .map(|line| {
26                            if line.trim_start().starts_with("current =") {
27                                format!("current = \"{}\"", lang)
28                            } else {
29                                line.to_string()
30                            }
31                        })
32                        .collect::<Vec<_>>()
33                        .join("\n")
34                } else {
35                    // Language section hinzufügen
36                    format!("{}\n\n[language]\ncurrent = \"{}\"", content.trim(), lang)
37                };
38
39                tokio::fs::write(&path, updated_content)
40                    .await
41                    .map_err(AppError::Io)?;
42
43                log::debug!("Language '{}' saved to config", lang.to_uppercase());
44                return Ok(());
45            }
46        }
47        Ok(())
48    }
49
50    /// Lädt Sprache aus Config-Datei
51    pub async fn load_from_config() -> Result<Option<String>> {
52        let config_paths = crate::setup::setup_toml::get_config_paths();
53
54        for path in config_paths {
55            if path.exists() {
56                let content = tokio::fs::read_to_string(&path)
57                    .await
58                    .map_err(AppError::Io)?;
59
60                // ✅ PARSE TOML für language.current
61                if let Some(lang) = Self::extract_language_from_toml(&content) {
62                    return Ok(Some(lang));
63                }
64            }
65        }
66        Ok(None)
67    }
68
69    /// Extrahiert language.current aus TOML String
70    fn extract_language_from_toml(content: &str) -> Option<String> {
71        let mut in_language_section = false;
72
73        for line in content.lines() {
74            let trimmed = line.trim();
75
76            if trimmed == "[language]" {
77                in_language_section = true;
78                continue;
79            }
80
81            if trimmed.starts_with('[') && trimmed.ends_with(']') && trimmed != "[language]" {
82                in_language_section = false;
83                continue;
84            }
85
86            if in_language_section && trimmed.starts_with("current =") {
87                if let Some(value_part) = trimmed.split('=').nth(1) {
88                    let cleaned = value_part.trim().trim_matches('"').trim_matches('\'');
89                    return Some(cleaned.to_string());
90                }
91            }
92        }
93        None
94    }
95
96    /// Überprüft ob Config-Datei existiert
97    pub fn config_exists() -> bool {
98        crate::setup::setup_toml::get_config_paths()
99            .iter()
100            .any(|path| path.exists())
101    }
102
103    /// Gibt alle möglichen Config-Pfade zurück
104    pub fn get_config_paths() -> Vec<PathBuf> {
105        crate::setup::setup_toml::get_config_paths()
106    }
107
108    /// Erstellt Backup der aktuellen Config vor Language-Änderung
109    pub async fn backup_config() -> Result<Option<PathBuf>> {
110        let config_paths = Self::get_config_paths();
111
112        for path in config_paths {
113            if path.exists() {
114                let backup_path = path.with_extension("toml.backup");
115                tokio::fs::copy(&path, &backup_path)
116                    .await
117                    .map_err(AppError::Io)?;
118
119                log::debug!("Config backup created: {}", backup_path.display());
120                return Ok(Some(backup_path));
121            }
122        }
123        Ok(None)
124    }
125}