1#[macro_export]
2macro_rules! impl_store {
3 ($($name:ty),+ $(,)?) => ($(
4 #[async_trait::async_trait]
5 impl $crate::store::Store for $name {
6 async fn new() -> Result<Self> {
7 use anyhow::{Context as _};
8
9 let path = Self::path()?;
10
11 if fs::metadata(path.clone()).await.is_err() {
12 return Self::default().save().await;
13 }
14
15 let mut file = File::open(path.clone())
16 .await
17 .context("Error opening file")?;
18
19 let mut buffer = String::new();
20 file.read_to_string(&mut buffer).await?;
21
22 serde_json::from_str(&buffer).context(format!("Failed to deserialize {} store", stringify!($name)))
23 }
24
25 async fn save(&self) -> Result<Self> {
26 use anyhow::{Context as _};
27
28 let path = Self::path()?;
29
30 fs::create_dir_all(path.parent().context("Failed to get store directory")?)
31 .await
32 .context("Failed to create store directory")?;
33
34 let mut file = File::create(path.clone())
35 .await
36 .context("Error opening file")?;
37
38 file.write_all(
39 serde_json::to_string(&self)
40 .context(format!("Failed to serialize {} store", stringify!($name)))?
41 .as_bytes(),
42 )
43 .await
44 .context("Failed to write store")?;
45
46 Ok(self.clone())
47 }
48 }
49 )+)
50}