specfold_core/files/
fetch.rs1use super::{hash, store};
4use crate::corpus::Corpus;
5use crate::model::Doc;
6use anyhow::{Context, Result, bail};
7use serde::Serialize;
8
9#[derive(Debug, Serialize)]
10pub struct Fetched {
11 pub path: String,
12 pub state: String,
14}
15
16pub fn fetch(c: &Corpus, doc: &Doc) -> Result<Vec<Fetched>> {
17 let entries: Vec<_> = doc.files().into_iter().filter(|f| f.store == "store").collect();
18 if entries.is_empty() {
19 return Ok(vec![]);
20 }
21 let s = store::open(&c.cfg)?.context("no [files.store] is configured")?;
22 let base = c.cfg.root.join(doc.base_dir());
23 let mut out = vec![];
24 for f in entries {
25 let dst = base.join(&f.path);
26 if dst.is_file() && hash::file(&dst).map(|h| h.0 == f.sha256).unwrap_or(false) {
27 out.push(Fetched { path: f.path, state: "present".into() });
28 continue;
29 }
30 s.get(&f.sha256, &dst)?;
31 let (got, _) = hash::file(&dst)?;
32 if got != f.sha256 {
33 bail!("{} arrived with sha256 {got}, expected {}", f.path, f.sha256);
34 }
35 out.push(Fetched { path: f.path, state: "fetched".into() });
36 }
37 Ok(out)
38}