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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
use std::fs::File;
use std::path::Path;

use super::base::SourceTrait;
#[cfg(feature = "look-ahead")]
use super::look_ahead_yes::PrebuiltData;
use super::root::SourceRoot;
use crate::error::*;

use serde::{de::DeserializeOwned, Serialize};

const PATH_CACHE: &str = "./.cache";
#[cfg(feature = "look-ahead")]
const PATH_CACHE_PREBUILT: &str = "./.prebuilt.cache";

impl<V, Imp> SourceRoot<V, Imp>
where
    Imp: SourceTrait,
{
    pub fn load<P>(root: P, imp: Imp) -> Result<Self>
    where
        P: AsRef<Path>,
        V: DeserializeOwned,
    {
        let root = root.as_ref();

        let path = root.join(PATH_CACHE);
        if path.exists() {
            let file = File::open(path)?;
            Ok(Self {
                #[cfg(feature = "look-ahead")]
                prebuilt: load_prebuilt_data(root, &imp)?,
                data: bincode::deserialize_from(file)?,
                root: root.to_owned(),
                imp,
            })
        } else {
            Self::new(root, imp)
        }
    }

    pub fn save(&self) -> Result<()>
    where
        V: Serialize,
    {
        #[cfg(feature = "look-ahead")]
        {
            let file = File::create(self.root.join(PATH_CACHE_PREBUILT))?;
            bincode::serialize_into(file, &self.prebuilt)?;
        }

        {
            let file = File::create(self.root.join(PATH_CACHE))?;
            bincode::serialize_into(file, &self.data)?;
        }
        Ok(())
    }
}

#[cfg(feature = "look-ahead")]
fn load_prebuilt_data<Imp>(root: &Path, imp: &Imp) -> Result<PrebuiltData<Imp::PrebuiltCode>>
where
    Imp: SourceTrait,
{
    let path = root.join(PATH_CACHE_PREBUILT);
    if path.exists() {
        let file = File::open(path)?;
        Ok(PrebuiltData {
            inner: bincode::deserialize_from(file)?,
        })
    } else {
        Ok(PrebuiltData::load(root, imp))
    }
}