1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
use crate::prelude::*;

mod encoding;
mod query;

#[derive(Debug)]
pub struct FilePersistence {
    root: PathBuf,
}

impl FilePersistence {
    pub fn new<P>(root: P) -> Self
    where
        P: Into<PathBuf>,
    {
        Self { root: root.into() }
    }
}

impl PersistenceTrait for FilePersistence {
    type Serialized = String;

    fn serialize(&self, entry: &Entry) -> Result<Self::Serialized> {
        encoding::encode(entry)
    }

    fn deserialize(&self, string: Self::Serialized) -> Result<Entry> {
        encoding::decode(string)
    }

    fn load(&self, path: &Path) -> Result<(PathBuf, Self::Serialized)> {
        Ok((path.into(), std::fs::read_to_string(path)?))
    }

    fn persist(&self, path: &Path, data: &Self::Serialized) -> Result<()> {
        let directory = path
            .parent()
            .with_context(|| format!("preparing directories for {path:?}"))?;
        std::fs::create_dir_all(directory)
            .with_context(|| format!("writing directorys for {path:?}"))?;
        std::fs::write(path, data).with_context(|| format!("saving {path:?}"))?;
        Ok(())
    }

    fn execute(&self, query: &Query) -> Result<Vec<(PathBuf, Self::Serialized)>> {
        query::run(&self.root, query)
    }
}