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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use chrono::NaiveDate;
use either::Either;
use manifest::Manifest;
use std::fs;
use std::path::{Path, PathBuf};
use Error;
pub trait Cache {
fn get(&self, day: NaiveDate) -> Option<Manifest>;
fn store(&self, manifest: &Manifest);
}
impl<L, R> Cache for Either<L, R>
where
L: Cache,
R: Cache,
{
fn get(&self, day: NaiveDate) -> Option<Manifest> {
match self {
Either::Left(x) => x.get(day),
Either::Right(x) => x.get(day),
}
}
fn store(&self, manifest: &Manifest) {
match self {
Either::Left(x) => x.store(manifest),
Either::Right(x) => x.store(manifest),
}
}
}
pub struct NoopCache {}
impl Cache for NoopCache {
fn get(&self, _day: NaiveDate) -> Option<Manifest> {
None
}
fn store(&self, _manifest: &Manifest) {}
}
pub struct FsCache {
storage_path: PathBuf,
}
impl FsCache {
pub fn new(path: impl AsRef<Path>) -> Result<Self, Error> {
let path = path.as_ref();
if !path.exists() {
fs::create_dir_all(path).map_err(|e| (e, format!("creating path {:?}", path)))?;
}
Ok(FsCache {
storage_path: path.into(),
})
}
fn make_file_name(&self, day: NaiveDate) -> PathBuf {
self.storage_path
.join(day.format("%Y-%m-%d.toml").to_string())
}
}
impl Cache for FsCache {
fn get(&self, day: NaiveDate) -> Option<Manifest> {
let file_name = self.make_file_name(day);
if !file_name.exists() {
debug!("File {:?} doesn't exist", file_name);
return None;
}
Manifest::load_from_fs(&file_name)
.map_err(|e| warn!("Can't load manifest: {}", e))
.ok()
}
fn store(&self, manifest: &Manifest) {
let file_name = self.make_file_name(manifest.date);
match manifest.save_to_file(&file_name) {
Ok(_) => debug!("Manifest stored at {:?}", file_name),
Err(e) => warn!("Can't save a manifest to the disk: {}", e),
}
}
}