use std::io::Write;
use std::path::{Path, PathBuf};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RetrievedArtifact {
pub blake3: String,
pub path: PathBuf,
pub size: u64,
}
#[derive(Debug, Clone)]
pub struct ContentAddressedStore {
root: PathBuf,
}
impl ContentAddressedStore {
pub fn new(root: impl Into<PathBuf>) -> Self {
Self { root: root.into() }
}
pub fn root(&self) -> &Path {
&self.root
}
pub fn land(&self, bytes: &[u8]) -> std::io::Result<RetrievedArtifact> {
let blake3 = blake3::hash(bytes).to_hex().to_string();
std::fs::create_dir_all(&self.root)?;
let path = self.root.join(&blake3);
if !path.exists() {
let tmp = self.root.join(format!(".tmp-{}-{}", std::process::id(), &blake3));
let mut f = std::fs::File::create(&tmp)?;
f.write_all(bytes)?;
f.sync_all()?;
std::fs::rename(&tmp, &path)?;
}
Ok(RetrievedArtifact {
blake3,
path,
size: bytes.len() as u64,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use tempfile::TempDir;
#[test]
fn land_is_content_addressed_and_preserves_blake3() {
let dir = TempDir::new().unwrap();
let store = ContentAddressedStore::new(dir.path().join("artifacts"));
let bytes = b"librusty_v8_release_x86_64-unknown-linux-musl.a bytes \x00\xff";
let landed = store.land(bytes).unwrap();
assert_eq!(landed.blake3, blake3::hash(bytes).to_hex().to_string());
assert_eq!(landed.path, store.root().join(&landed.blake3));
assert_eq!(landed.size, bytes.len() as u64);
let on_disk = std::fs::read(&landed.path).unwrap();
assert_eq!(on_disk, bytes);
assert_eq!(blake3::hash(&on_disk).to_hex().to_string(), landed.blake3);
}
#[test]
fn land_is_idempotent_for_identical_bytes() {
let dir = TempDir::new().unwrap();
let store = ContentAddressedStore::new(dir.path().join("artifacts"));
let bytes = b"same bytes twice";
let a = store.land(bytes).unwrap();
let b = store.land(bytes).unwrap();
assert_eq!(a, b, "re-landing identical bytes returns the same address");
let entries: Vec<_> = std::fs::read_dir(store.root())
.unwrap()
.map(|e| e.unwrap().file_name().to_string_lossy().into_owned())
.collect();
assert_eq!(entries, vec![a.blake3], "one content-addressed blob, no temp debris");
}
#[test]
fn distinct_bytes_land_at_distinct_addresses() {
let dir = TempDir::new().unwrap();
let store = ContentAddressedStore::new(dir.path().join("artifacts"));
let a = store.land(b"alpha").unwrap();
let b = store.land(b"beta").unwrap();
assert_ne!(a.blake3, b.blake3);
assert_ne!(a.path, b.path);
}
}