summaryrefslogtreecommitdiff
path: root/src-tauri/src/storage.rs
diff options
context:
space:
mode:
authorSolstice <solstice@local>2026-06-09 00:17:02 -0700
committerSolstice <solstice@local>2026-06-09 00:17:02 -0700
commit25e1dcf205cd14feafdd9b4cf6b7a66f253ba6d2 (patch)
treedbb093278df115040a67791367711f06e57d3d3a /src-tauri/src/storage.rs
parent72626524c4a1c7d6642bc170520913273acb1a5c (diff)
fix: backend code review — atomic writes, lock ordering, validation
Diffstat (limited to 'src-tauri/src/storage.rs')
-rw-r--r--src-tauri/src/storage.rs14
1 files changed, 11 insertions, 3 deletions
diff --git a/src-tauri/src/storage.rs b/src-tauri/src/storage.rs
index 28b1f86..8e2f148 100644
--- a/src-tauri/src/storage.rs
+++ b/src-tauri/src/storage.rs
@@ -57,10 +57,15 @@ pub fn load(app_data_dir: &PathBuf) -> AppData {
if !path.exists() {
return AppData::default();
}
- match fs::read_to_string(&path) {
+ let mut data = match fs::read_to_string(&path) {
Ok(contents) => serde_json::from_str(&contents).unwrap_or_default(),
Err(_) => AppData::default(),
+ };
+ // Guard against a corrupt/zero value that would cause division by zero
+ if data.settings.sessions_before_long_break == 0 {
+ data.settings.sessions_before_long_break = Settings::default().sessions_before_long_break;
}
+ data
}
pub fn save(app_data_dir: &PathBuf, data: &AppData) -> Result<(), String> {
@@ -69,7 +74,10 @@ pub fn save(app_data_dir: &PathBuf, data: &AppData) -> Result<(), String> {
let path = data_path(app_data_dir);
let contents = serde_json::to_string_pretty(data)
.map_err(|e| format!("Failed to serialize data: {}", e))?;
- fs::write(&path, contents)
- .map_err(|e| format!("Failed to write data file: {}", e))?;
+ let tmp_path = app_data_dir.join("data.json.tmp");
+ fs::write(&tmp_path, contents)
+ .map_err(|e| format!("Failed to write temp data file: {}", e))?;
+ fs::rename(&tmp_path, &path)
+ .map_err(|e| format!("Failed to finalize data file: {}", e))?;
Ok(())
}