pub mod clock;
mod error;
pub mod file;
pub mod fs;
pub mod journal;
pub mod memory;
pub mod merge_driver;
pub mod repository;
use loftspec::codec::{Files, Role, SpecPath};
use loftspec::document::Document;
use loftspec::hash::{Roots, hash_document};
pub use error::StoreError;
pub use file::FileStore;
pub use memory::MemoryStore;
pub trait DocumentStore {
fn load(&self) -> Result<Document, StoreError>;
fn save(&mut self, document: &Document) -> Result<Saved, StoreError>;
fn roots(&self) -> Result<Roots, StoreError> {
hash_document(&self.load()?)
.map(|hashes| hashes.roots)
.map_err(StoreError::Index)
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct Saved {
pub written: Vec<SpecPath>,
pub removed: Vec<SpecPath>,
}
impl Saved {
#[must_use]
pub fn between(current: &Files, next: &Files) -> Self {
let written = next
.iter()
.filter(|(path, bytes)| current.get(*path) != Some(*bytes))
.map(|(path, _)| path.clone())
.collect();
let removed = current
.keys()
.filter(|path| !next.contains_key(*path))
.filter(|path| Role::of(path).is_some_and(|role| role.is_written()))
.cloned()
.collect();
Self { written, removed }
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.written.is_empty() && self.removed.is_empty()
}
}