mod local;
pub use local::{LocalStore, CACHE_VERSION};
use std::collections::HashMap;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use crate::error::Result;
use crate::manifest::Manifest;
pub struct StagingFile {
temp: tempfile::NamedTempFile,
}
impl StagingFile {
pub(crate) fn new(temp: tempfile::NamedTempFile) -> Self {
Self { temp }
}
pub fn path(&self) -> &Path {
self.temp.path()
}
pub(crate) fn into_temp(self) -> tempfile::NamedTempFile {
self.temp
}
}
pub struct BlobLock {
_file: std::fs::File,
}
impl BlobLock {
pub(crate) fn new(file: std::fs::File) -> Self {
Self { _file: file }
}
}
pub trait Store: Send + Sync {
fn name(&self) -> &str;
fn exists(&self, key: &str) -> bool;
fn get_blob(&self, key: &str) -> Option<PathBuf>;
fn get_blob_hinted(&self, key: &str, ext: &str) -> Option<PathBuf> {
let _ = ext;
self.get_blob(key)
}
fn get_meta(&self, key: &str) -> Result<Option<Manifest>>;
fn put_meta(&self, key: &str, manifest: &Manifest) -> Result<()>;
fn new_staging(&self) -> Result<StagingFile>;
fn commit_blob(&self, key: &str, staged: StagingFile, ext: &str) -> Result<PathBuf>;
fn lock(&self, key: &str) -> Result<BlobLock>;
}
#[derive(Default, Clone)]
pub struct StoreRegistry {
by_name: HashMap<String, Arc<dyn Store>>,
}
impl StoreRegistry {
pub fn new() -> Self {
Self::default()
}
pub fn with_local(root: impl Into<PathBuf>) -> Self {
let mut r = Self::new();
r.register(Arc::new(LocalStore::new(root)));
r
}
pub fn register(&mut self, store: Arc<dyn Store>) -> &mut Self {
self.by_name.insert(store.name().to_string(), store);
self
}
pub fn get(&self, name: &str) -> Option<Arc<dyn Store>> {
self.by_name.get(name).cloned()
}
pub fn registered(&self) -> Vec<String> {
self.by_name.keys().cloned().collect()
}
}