atagen

roundabout

public
Star0
Watch0
6eb193fbfa7079255854358bcf4ae83a78070087
1
ssh://brewery@pls.lobotomise.me:33/atagen/roundabout.git

Blame: src/store.rs

6f5b84fad3efatagen2026-09-27 03:59 UTC1
use std::{fs, io, path::PathBuf};
6f5b84fad3efatagen2026-09-27 03:59 UTC2
6f5b84fad3efatagen2026-09-27 03:59 UTC3
use serde::{Serialize, de::DeserializeOwned};
6f5b84fad3efatagen2026-09-27 03:59 UTC4
6f5b84fad3efatagen2026-09-27 03:59 UTC5
use crate::{client::Flock, paths};
6f5b84fad3efatagen2026-09-27 03:59 UTC6
6f5b84fad3efatagen2026-09-27 03:59 UTC7
fn path(name: &str) -> PathBuf {
6f5b84fad3efatagen2026-09-27 03:59 UTC8
    paths::state_dir().join(format!("{name}.json"))
6f5b84fad3efatagen2026-09-27 03:59 UTC9
}
6f5b84fad3efatagen2026-09-27 03:59 UTC10
6f5b84fad3efatagen2026-09-27 03:59 UTC11
pub fn load<T: DeserializeOwned + Default>(name: &str) -> T {
6f5b84fad3efatagen2026-09-27 03:59 UTC12
    fs::read(path(name))
6f5b84fad3efatagen2026-09-27 03:59 UTC13
        .ok()
6f5b84fad3efatagen2026-09-27 03:59 UTC14
        .and_then(|b| serde_json::from_slice(&b).ok())
6f5b84fad3efatagen2026-09-27 03:59 UTC15
        .unwrap_or_default()
6f5b84fad3efatagen2026-09-27 03:59 UTC16
}
6f5b84fad3efatagen2026-09-27 03:59 UTC17
6f5b84fad3efatagen2026-09-27 03:59 UTC18
/// readers skip the lock, the rename keeps them from seeing half a file
6f5b84fad3efatagen2026-09-27 03:59 UTC19
pub fn update<T, R>(name: &str, f: impl FnOnce(&mut T) -> R) -> io::Result<R>
6f5b84fad3efatagen2026-09-27 03:59 UTC20
where
6f5b84fad3efatagen2026-09-27 03:59 UTC21
    T: Serialize + DeserializeOwned + Default,
6f5b84fad3efatagen2026-09-27 03:59 UTC22
{
6f5b84fad3efatagen2026-09-27 03:59 UTC23
    let lock = fs::OpenOptions::new()
6f5b84fad3efatagen2026-09-27 03:59 UTC24
        .create(true)
6f5b84fad3efatagen2026-09-27 03:59 UTC25
        .truncate(false)
6f5b84fad3efatagen2026-09-27 03:59 UTC26
        .write(true)
6f5b84fad3efatagen2026-09-27 03:59 UTC27
        .open(paths::state_dir().join(format!("{name}.lock")))?;
6f5b84fad3efatagen2026-09-27 03:59 UTC28
    let _guard = Flock::exclusive(lock)?;
6f5b84fad3efatagen2026-09-27 03:59 UTC29
    let mut value = load(name);
6f5b84fad3efatagen2026-09-27 03:59 UTC30
    let out = f(&mut value);
6f5b84fad3efatagen2026-09-27 03:59 UTC31
    let tmp = path(&format!("{name}.tmp"));
6f5b84fad3efatagen2026-09-27 03:59 UTC32
    fs::write(&tmp, serde_json::to_vec(&value)?)?;
6f5b84fad3efatagen2026-09-27 03:59 UTC33
    fs::rename(tmp, path(name))?;
6f5b84fad3efatagen2026-09-27 03:59 UTC34
    Ok(out)
6f5b84fad3efatagen2026-09-27 03:59 UTC35
}