shard-core 2.0.0

Core library for shard distributed VCS: chunking, compression, commits, branching, merging, WAL
Documentation
pub mod flat;
pub mod sled;
pub mod sqlite;

use crate::chunker::Chunk;
use crate::metadata;
use anyhow::Result;
use std::path::Path;

pub enum Store {
    Flat(flat::FlatStore),
    Sled(sled::SledStore),
    Sqlite(sqlite::SqliteStore),
}

impl Store {
    pub fn new(root: &Path, backend: &str) -> Result<Self> {
        match backend {
            "flat" => Ok(Store::Flat(flat::FlatStore::new(root))),
            "sled" => Ok(Store::Sled(sled::SledStore::new(root)?)),
            "sqlite" => Ok(Store::Sqlite(sqlite::SqliteStore::new(root)?)),
            _ => anyhow::bail!("Unknown storage backend: {}", backend),
        }
    }

    pub fn open(root: &Path) -> Result<Self> {
        let config_path = root.join("config.json");
        let backend = if config_path.exists() {
            let data = std::fs::read(&config_path)?;
            let config: std::collections::BTreeMap<String, String> = metadata::deserialize(&data)?;
            config
                .get("storage_backend")
                .map(|s| s.as_str())
                .unwrap_or("flat")
                .to_string()
        } else {
            "flat".to_string()
        };
        Self::new(root, &backend)
    }

    pub fn put_chunk(&self, chunk: &Chunk) -> Result<()> {
        match self {
            Store::Flat(s) => s.put_chunk(chunk),
            Store::Sled(s) => s.put_chunk(chunk),
            Store::Sqlite(s) => s.put_chunk(chunk),
        }
    }

    pub fn get_chunk(&self, hash_hex: &str) -> Result<Vec<u8>> {
        match self {
            Store::Flat(s) => s.get_chunk(hash_hex),
            Store::Sled(s) => s.get_chunk(hash_hex),
            Store::Sqlite(s) => s.get_chunk(hash_hex),
        }
    }

    pub fn has_chunk(&self, hash_hex: &str) -> bool {
        match self {
            Store::Flat(s) => s.has_chunk(hash_hex),
            Store::Sled(s) => s.has_chunk(hash_hex),
            Store::Sqlite(s) => s.has_chunk(hash_hex),
        }
    }

    pub fn iter_chunks(&self) -> Result<Vec<(String, String)>> {
        match self {
            Store::Flat(s) => s.iter_chunks(),
            Store::Sled(s) => s.iter_chunks(),
            Store::Sqlite(s) => s.iter_chunks(),
        }
    }

    pub fn delete_chunk(&self, hash_hex: &str, full_path: Option<&str>) -> Result<()> {
        match self {
            Store::Flat(s) => s.delete_chunk(hash_hex, full_path),
            Store::Sled(s) => s.delete_chunk(hash_hex, full_path),
            Store::Sqlite(s) => s.delete_chunk(hash_hex, full_path),
        }
    }
}