hoc/src/cache.rs

65 lines
1.7 KiB
Rust
Raw Normal View History

2019-06-16 22:20:09 +02:00
use crate::error::{Error, Result};
2019-04-19 22:51:58 +02:00
use std::{
2019-04-29 20:37:20 +02:00
borrow::Cow,
2019-04-19 22:51:58 +02:00
fs::{create_dir_all, File, OpenOptions},
io::BufReader,
path::Path,
};
/// Enum to indicate the state of the cache
2019-04-29 20:37:20 +02:00
pub(crate) enum CacheState<'a> {
2019-04-19 22:51:58 +02:00
/// Current head and cached head are the same
Current(u64),
/// Cached head is older than current head
2019-04-29 20:37:20 +02:00
Old(Cache<'a>),
2019-04-19 22:51:58 +02:00
/// No cache was found
No,
}
2019-04-29 20:37:20 +02:00
impl<'a> CacheState<'a> {
2019-06-16 22:20:09 +02:00
pub(crate) fn read_from_file(path: impl AsRef<Path>, head: &str) -> Result<CacheState> {
2019-04-19 22:51:58 +02:00
if path.as_ref().exists() {
let cache: Cache = serde_json::from_reader(BufReader::new(File::open(path)?))?;
if cache.head == head {
Ok(CacheState::Current(cache.count))
} else {
Ok(CacheState::Old(cache))
}
} else {
Ok(CacheState::No)
}
}
2019-04-29 20:37:20 +02:00
pub(crate) fn calculate_new_cache(self, count: u64, head: Cow<'a, str>) -> Cache {
2019-04-19 22:51:58 +02:00
match self {
CacheState::Old(mut cache) => {
cache.head = head;
cache.count += count;
cache
}
CacheState::No | CacheState::Current(_) => Cache { head, count },
}
}
}
#[derive(Serialize, Deserialize)]
2019-04-29 20:37:20 +02:00
pub(crate) struct Cache<'a> {
pub head: Cow<'a, str>,
2019-04-19 22:51:58 +02:00
pub count: u64,
}
2019-04-29 20:37:20 +02:00
impl<'a> Cache<'a> {
2019-06-16 22:20:09 +02:00
pub(crate) fn write_to_file(&self, path: impl AsRef<Path>) -> Result<()> {
2019-04-19 22:51:58 +02:00
create_dir_all(path.as_ref().parent().ok_or(Error::Internal)?)?;
serde_json::to_writer(
OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(path)?,
self,
)?;
Ok(())
}
}