specfold_core/files/store/
dir.rs1use 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}