libasuran 0.0.3

Deduplicating, encrypting, fast, and tamper evident archive format
Documentation
//! The backend provides abstract IO access to the real location of the data in
//! the repository.
use std::io::Result;

pub mod filesystem;

/// Segments are abstract blocks of chunks
///
/// Backends are free to arrange chunks within segements any way they wish,
/// as long as they only ever append to existing segments.
///
/// Segement compaction must happen through writing new segments and deleting
/// the old ones
pub trait Segment {
    /// Returns the free bytes in this segment
    fn free_bytes(&self) -> u64;
    /// Reads a chunk from the segment into a bytestring
    ///
    /// Requires the start and end positions for the chunk
    ///
    /// Will return None if the read fails
    fn read_chunk(&mut self, start: u64, length: u64) -> Option<Vec<u8>>;
    /// Writes a chunk to the segment
    ///
    /// Retuns Some(start,length), or None if writing fails
    fn write_chunk(&mut self, chunk: &[u8]) -> Option<(u64, u64)>;
}

/// Repository backend
///
/// The backend handles the heavy lifiting of the IO, abstracting the repository
/// struct itself away from the details of the system used to store the repository.
///
/// Cloning a backend should result in a new view over the same storage, and clones
/// should play nice with multithreaded access.
pub trait Backend: Send + Sync + Clone {
    /// Gets a particular segment
    ///
    /// Returns None if it does not exist or can not be found
    fn get_segment(&self, id: u64) -> Option<Box<dyn Segment>>;
    /// Returns the id of the higest segment
    fn highest_segment(&self) -> u64;
    /// Creates a new segment
    ///
    /// Returns Some(id) with the segement if it can be created
    /// Returns None if creation fails.
    fn make_segment(&self) -> Option<u64>;
    /// Returns the index of the repository
    ///
    /// Indexes are stored as byte strings, intrepreation is up to the caller
    fn get_index(&self) -> Vec<u8>;
    /// Writes a new index to the backend
    ///
    /// Backend should write the new index first, and then delete the old one
    ///
    /// Returns Err if the index could not be written.
    fn write_index(&self, index: &[u8]) -> Result<()>;
}