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
use crate::{IoError, IoResult};
use std::path::{Path, PathBuf};
use std::time::Duration;
#[cfg(feature = "http_client")]
use crate::{document::DEFAULT_MEMORY_SIZE, Document};
#[cfg(feature = "http_client")]
pub fn download_if_not_stale<P: AsRef<Path>>(
url: &str,
cache_dir: &Path,
resource_path: P,
timeout: Duration,
) -> IoResult<Document> {
use attohttpc as http_client;
use std::io::{BufWriter, Write};
let manifest_path = cache_dir.join(resource_path);
if manifest_path.exists() && !is_stale(&manifest_path, timeout)? {
return Ok(Document::LocalPath(manifest_path));
} else {
std::fs::create_dir_all(cache_dir)?;
}
let response = http_client::get(url)
.header(
"User-Agent",
"rust-releases (github.com/foresterre/rust-releases/issues)",
)
.send()?;
let mut memory = Vec::with_capacity(DEFAULT_MEMORY_SIZE);
response.write_to(&mut memory)?;
let mut file = std::fs::File::create(&manifest_path)?;
let mut writer = BufWriter::new(&mut file);
writer.write_all(&memory)?;
Ok(Document::RemoteCached(manifest_path, memory))
}
pub fn is_stale<P: AsRef<Path>>(path: P, timeout: Duration) -> IoResult<bool> {
let metadata = std::fs::metadata(path)?;
let modification = metadata.modified()?;
let duration = modification.elapsed()?;
Ok(timeout < duration)
}
pub fn base_cache_dir() -> IoResult<PathBuf> {
let cache = directories_next::ProjectDirs::from("com", "ilumeo", "rust-releases")
.ok_or(IoError::DlCache)?;
let cache = cache.cache_dir();
Ok(cache.to_path_buf())
}