use std::collections::{BTreeSet, HashMap};
use std::fs::File;
use std::io::Read;
use std::path::Path;
use anyhow::Result;
use super::index;
pub(super) type Body = Box<dyn Read + Send>;
#[derive(Clone, Copy)]
pub(super) enum Object<'a> {
Entry(&'a str),
Warm { identity: &'a str, branch: &'a str },
Blob(&'a str),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(super) enum Framing {
Pack,
Upload,
}
pub(super) fn warm_names(identity: &str, branch: &str) -> (String, String) {
let hash = |text: &str| blake3::hash(text.as_bytes()).to_hex()[..32].to_owned();
let identity = format!(
"{identity}\0{}\0{}",
std::env::consts::OS,
std::env::consts::ARCH
);
(hash(&identity), hash(branch))
}
#[derive(Debug)]
pub(super) struct MissingBlobs(pub Vec<String>);
impl std::fmt::Display for MissingBlobs {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(formatter, "the store lacks {} blobs", self.0.len())
}
}
impl std::error::Error for MissingBlobs {}
pub(super) trait Store: Send + Sync {
fn framing(&self) -> Framing {
Framing::Pack
}
fn begin(&self, _root: &Path) {}
fn get_blob(&self, hash: &str, _owner: Object, task: &str) -> Result<Option<Body>> {
self.get(Object::Blob(hash), task)
}
fn location(&self) -> String;
fn sync_index(&self, known: &mut index::Known) -> Result<()>;
fn get(&self, object: Object, task: &str) -> Result<Option<Body>>;
fn has(&self, object: Object) -> Result<bool>;
fn put(&self, object: Object, file: File) -> Result<()>;
fn announce(&self, key: &str, apart: &[String]) -> Result<Option<String>>;
fn list(
&self,
keys: BTreeSet<String>,
apart: HashMap<String, Vec<String>>,
members: Vec<String>,
known: Option<&index::Known>,
announcements: BTreeSet<String>,
) -> Result<()>;
}