Skip to main content

supreme_config/
parser.rs

1use anyhow::{Context, Result};
2use std::fs;
3use std::path::Path;
4use supreme_fs::GameStorage;
5
6use crate::models::{
7    DetailConfig, DisplayConfig, LanguageConfig, MaterialConfig, SoundConfig, TrainerConfig,
8};
9use supreme_parsing::Error;
10
11// DisplayConfig I/O
12impl DisplayConfig {
13    #[must_use]
14    pub fn load(storage: &GameStorage, path: &Path) -> Self {
15        supreme_parsing::from_file(storage, path).unwrap_or_else(|e| {
16            match e {
17                Error::Io(err) if err.kind() == std::io::ErrorKind::NotFound => {
18                    // Silently return default for missing file (will be created on save)
19                }
20                _ => {
21                    eprintln!("DisplayConfig load error ({}): {}", path.display(), e);
22                }
23            }
24            DisplayConfig::default()
25        })
26    }
27
28    pub fn save(&self, storage: &GameStorage, path: &Path) -> Result<()> {
29        supreme_parsing::to_file(storage, path, self)?;
30        Ok(())
31    }
32}
33
34// DetailConfig I/O
35impl DetailConfig {
36    #[must_use]
37    pub fn load(storage: &GameStorage, path: &Path) -> Self {
38        supreme_parsing::from_file(storage, path).unwrap_or_else(|e| {
39            match e {
40                Error::Io(err) if err.kind() == std::io::ErrorKind::NotFound => {
41                    // Silently return default for missing file (will be created on save)
42                }
43                _ => {
44                    eprintln!("DetailConfig load error ({}): {}", path.display(), e);
45                }
46            }
47            DetailConfig::default()
48        })
49    }
50
51    pub fn save(&self, storage: &GameStorage, path: &Path) -> Result<()> {
52        supreme_parsing::to_file(storage, path, self)?;
53        Ok(())
54    }
55}
56
57// SoundConfig I/O
58impl SoundConfig {
59    #[must_use]
60    pub fn load(storage: &GameStorage, path: &Path) -> Self {
61        supreme_parsing::from_file(storage, path).unwrap_or_else(|e| {
62            match e {
63                Error::Io(err) if err.kind() == std::io::ErrorKind::NotFound => {
64                    // Silently return default for missing file (will be created on save)
65                }
66                _ => {
67                    eprintln!("SoundConfig load error ({}): {}", path.display(), e);
68                }
69            }
70            SoundConfig::default()
71        })
72    }
73
74    pub fn save(&self, storage: &GameStorage, path: &Path) -> Result<()> {
75        supreme_parsing::to_file(storage, path, self)?;
76        Ok(())
77    }
78}
79
80// HelperConfig I/O (JSON)
81impl TrainerConfig {
82    #[must_use]
83    pub fn load(path: &Path) -> Self {
84        let content = match fs::read_to_string(path) {
85            Ok(c) => c,
86            Err(_) => return Self::default(),
87        };
88
89        serde_json::from_str(&content).unwrap_or_default()
90    }
91
92    pub fn save(&self, path: &Path) -> Result<()> {
93        fs::create_dir_all(path.parent().unwrap_or(Path::new(".")))?;
94        let json = serde_json::to_string_pretty(self)?;
95        if let Err(e) = fs::write(path, json) {
96            eprintln!("TrainerConfig save error ({}): {}", path.display(), e);
97            return Err(anyhow::anyhow!("Failed to write TrainerConfig: {e}"));
98        }
99        Ok(())
100    }
101}
102
103// LanguageConfig I/O (simple text file)
104impl LanguageConfig {
105    #[must_use]
106    pub fn load(storage: &GameStorage, path: &Path) -> Self {
107        let language = match storage.read_text(path) {
108            Ok(content) => content.trim().to_string(),
109            Err(e) if e.kind() == std::io::ErrorKind::NotFound => "English".to_string(),
110            Err(e) => {
111                eprintln!("LanguageConfig load error ({}): {}", path.display(), e);
112                "English".to_string()
113            }
114        };
115
116        LanguageConfig { language }
117    }
118
119    pub fn save(&self, storage: &GameStorage, path: &Path) -> Result<()> {
120        fs::create_dir_all(path.parent().unwrap_or(Path::new(".")))?;
121        storage
122            .write_text(path, &self.language)
123            .context("Failed to write LanguageConfig")?;
124        Ok(())
125    }
126}
127
128// MaterialConfig I/O
129impl MaterialConfig {
130    #[must_use]
131    pub fn load(storage: &GameStorage, path: &Path) -> Self {
132        supreme_parsing::from_file(storage, path).unwrap_or_else(|e| {
133            match e {
134                Error::Io(err) if err.kind() == std::io::ErrorKind::NotFound => {
135                    // Silently return default for missing file
136                }
137                _ => {
138                    eprintln!("MaterialConfig load error ({}): {}", path.display(), e);
139                }
140            }
141            MaterialConfig::default()
142        })
143    }
144
145    pub fn save(&self, storage: &GameStorage, path: &Path) -> Result<()> {
146        supreme_parsing::to_file(storage, path, self)?;
147        Ok(())
148    }
149}