diff options
| author | Mica White <botahamec@outlook.com> | 2026-07-29 21:19:57 -0400 |
|---|---|---|
| committer | Mica White <botahamec@outlook.com> | 2026-07-29 21:19:57 -0400 |
| commit | c687e2aba30ca231b03288108b632f1bad464028 (patch) | |
| tree | 6134233d24211510eb674417d3374615a74b8268 /src/storage.rs | |
| parent | 20ecfc902cc5a654a079e9ba22c41179aca221bb (diff) | |
Diffstat (limited to 'src/storage.rs')
| -rw-r--r-- | src/storage.rs | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/storage.rs b/src/storage.rs new file mode 100644 index 0000000..90abf05 --- /dev/null +++ b/src/storage.rs @@ -0,0 +1,41 @@ +use etcetera::{AppStrategy, AppStrategyArgs, app_strategy::Xdg}; +use smol::unblock; + +pub struct StorageManager { + xdg: Xdg, + data: Option<Box<[u8]>>, +} + +impl StorageManager { + pub fn load(app: AppStrategyArgs) -> std::io::Result<Self> { + let xdg = etcetera::choose_app_strategy(app).map_err(std::io::Error::other)?; + let data = std::fs::read(xdg.in_data_dir("save")) + .or_else(|_| std::fs::read(xdg.in_data_dir("save.tmp"))) + .map(|data| data.into_boxed_slice()) + .ok(); + + Ok(Self { data, xdg }) + } + + pub fn get(&self) -> Option<&[u8]> { + self.data.as_deref() + } + + pub fn background_save(&mut self, data: Box<[u8]>) { + let tmp_file = self.xdg.in_data_dir("save.tmp"); + let save_file = self.xdg.in_data_dir("save"); + + self.data = Some(data.clone()); + unblock(move || { + std::fs::write(&tmp_file, &data)?; + + let saved_data = std::fs::read(&tmp_file)?; + if *saved_data != *data { + return Err(std::io::Error::other("Failed to verify file integrity")); + } + + std::fs::rename(tmp_file, save_file)?; + Ok(()) + }); + } +} |
