bakare 0.1.0

modern and simple, yet efficient backup solution
Documentation
use crate::{repository::ItemId, version::Version};
use anyhow::Result;
use anyhow::*;
use nix::unistd::getpid;
use std::fmt;
use std::fmt::{Display, Formatter};
use std::path::Path;
use vfs::VfsPath;

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RepositoryItem {
    relative_path: String,
    absolute_path: VfsPath,
    original_source_path: String,
    id: ItemId,
    version: Version,
}

impl PartialOrd for RepositoryItem {
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        self.id.partial_cmp(&other.id)
    }
}

impl RepositoryItem {
    pub fn from(
        original_source_path: &str,
        absolute_path: &VfsPath,
        relative_path: &str,
        id: ItemId,
        version: Version,
    ) -> Self {
        RepositoryItem {
            relative_path: relative_path.to_string(),
            absolute_path: absolute_path.clone(),
            original_source_path: original_source_path.to_string(),
            id,
            version,
        }
    }

    pub fn save(&self, save_to: &VfsPath) -> Result<()> {
        let original_source_path = Path::new(self.original_source_path());
        let source_path_relative = original_source_path.strip_prefix("/")?;
        let source_path_relative = source_path_relative.to_string_lossy();
        let target_path = save_to.join(&source_path_relative)?;
        let parent = target_path
            .parent()
            .ok_or_else(|| anyhow!("cannot compute parent path for {}", &target_path.as_str()))?;
        log::debug!("[{}] saving data to {}", getpid(), target_path.as_str());
        parent.create_dir_all()?;
        if !self.absolute_path.exists() {
            return Err(anyhow!("corrupted repository"));
        }
        self.absolute_path.copy_file(&target_path)?;

        Ok(())
    }

    pub fn relative_path(&self) -> &str {
        &self.relative_path
    }

    pub fn original_source_path(&self) -> &str {
        &self.original_source_path
    }

    pub fn version(&self) -> &Version {
        &self.version
    }

    pub fn id(&self) -> &ItemId {
        &self.id
    }
}

impl Display for RepositoryItem {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "'{}' : {}", self.original_source_path(), hex::encode(self.id()))
    }
}