asimov_server/
persistence.rs1use serde::{Deserialize, Serialize};
4use std::{
5 path::PathBuf,
6 sync::{Arc, LazyLock, RwLock},
7};
8use thiserror::Error;
9
10#[derive(Debug, Error)]
11pub enum Error {
12 #[error("failed to read or write")]
13 IoError(#[from] std::io::Error),
14 #[error("failed to serialize or deserialize")]
15 SerdeError(#[from] serde_json::Error),
16}
17pub type Result<T> = std::result::Result<T, Error>;
18
19static STATE: LazyLock<Arc<RwLock<PersistentState>>> =
20 LazyLock::new(|| Arc::new(RwLock::new(read().unwrap_or_default())));
21
22#[derive(Debug, Clone, Serialize, Deserialize)]
23#[serde(default)]
24pub struct PersistentState {
25 pub provider: String,
26}
27
28impl Default for PersistentState {
29 fn default() -> Self {
30 Self {
31 provider: "asimov-default-provider".into(),
32 }
33 }
34}
35
36fn get_file_path() -> Result<PathBuf> {
38 let current_dir = std::env::current_exe()?;
39 Ok(current_dir.with_file_name("persistence.json"))
40}
41
42fn read() -> Result<PersistentState> {
44 let path = get_file_path()?;
45 let file = std::fs::File::open(path)?;
46 let reader = std::io::BufReader::new(file);
47 Ok(serde_json::from_reader(reader)?)
48}
49
50fn write(state: &PersistentState) -> Result<()> {
52 let path = get_file_path()?;
53 let file = std::fs::File::create(path)?;
54 let writer = std::io::BufWriter::new(file);
55 serde_json::to_writer(writer, state)?;
56 Ok(())
57}
58
59pub(crate) fn get_ref() -> Arc<RwLock<PersistentState>> {
61 STATE.clone()
62}
63
64pub fn get() -> PersistentState {
66 STATE.read().unwrap().clone()
67}
68
69pub fn set<F>(x: F) -> Result<()>
76where
77 F: FnOnce(&mut PersistentState),
78{
79 let mut state = STATE.write().unwrap();
80 x(&mut state);
81 write(&state)
82}