blob: 90abf059f9a424a02467eb75d2e6a758619d065b (
plain)
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(())
});
}
}
|