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
11impl 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 }
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
34impl 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 }
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
57impl 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 }
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
80impl 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
103impl 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
128impl 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 }
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}