Skip to main content

specfold_core/files/store/
dir.rs

1//! A store that is a plain directory: a shared drive, a synced folder, or a test fixture.
2
3use super::types::Store;
4use anyhow::{Context, Result};
5use std::path::{Path, PathBuf};
6
7pub struct DirStore {
8    pub root: PathBuf,
9}
10
11impl DirStore {
12    fn object(&self, key: &str) -> PathBuf {
13        self.root.join(&key[..2.min(key.len())]).join(key)
14    }
15}
16
17impl Store for DirStore {
18    fn put(&self, src: &Path, key: &str) -> Result<()> {
19        let dst = self.object(key);
20        if dst.is_file() {
21            return Ok(());
22        }
23        std::fs::create_dir_all(dst.parent().unwrap_or(&self.root))?;
24        std::fs::copy(src, &dst).with_context(|| format!("cannot copy into {}", dst.display()))?;
25        Ok(())
26    }
27
28    fn get(&self, key: &str, dst: &Path) -> Result<()> {
29        if let Some(p) = dst.parent() {
30            std::fs::create_dir_all(p)?;
31        }
32        std::fs::copy(self.object(key), dst)
33            .with_context(|| format!("object {key} is not in {}", self.root.display()))?;
34        Ok(())
35    }
36
37    fn exists(&self, key: &str) -> Result<Option<bool>> {
38        Ok(Some(self.object(key).is_file()))
39    }
40}