diff --git a/src/index.rs b/src/index.rs index 0b7d5e2..17854df 100644 --- a/src/index.rs +++ b/src/index.rs @@ -5,12 +5,16 @@ use serde::{Deserialize, Serialize}; use crate::error::BakareError; use crate::repository_item::RepositoryItem; use std::fs::File; +use std::ops::Deref; + +#[derive(Clone, Debug, PartialOrd, PartialEq, Ord, Eq, Serialize, Deserialize)] +pub struct ItemVersion(Box<[u8]>); #[derive(Clone, Debug, PartialOrd, PartialEq, Ord, Eq, Serialize, Deserialize)] pub struct IndexItem { relative_path: String, original_source_path: String, - version: Box<[u8]>, + version: ItemVersion, } #[derive(Serialize, Deserialize)] @@ -20,6 +24,26 @@ pub struct Index { repository_path: String, } +impl AsRef<[u8]> for ItemVersion { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} + +impl Deref for ItemVersion { + type Target = [u8]; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From<&[u8]> for ItemVersion { + fn from(a: &[u8]) -> Self { + ItemVersion(Box::from(a)) + } +} + impl Index { pub fn new(repository_path: &Path) -> Self { Index { @@ -81,7 +105,7 @@ impl From for IndexItem { IndexItem { relative_path: i.relative_path().to_string_lossy().to_string(), original_source_path: i.original_source_path().to_string_lossy().to_string(), - version: i.version(), + version: i.version().clone(), } } } diff --git a/src/repository.rs b/src/repository.rs index b191a4d..31e4fc7 100644 --- a/src/repository.rs +++ b/src/repository.rs @@ -2,7 +2,7 @@ use std::path::Path; use std::{fs, io}; use crate::error::BakareError; -use crate::index::{Index, IndexIterator}; +use crate::index::{Index, IndexIterator, ItemVersion}; use crate::repository_item::RepositoryItem; use sha2::Digest; use sha2::Sha512; @@ -82,15 +82,14 @@ impl<'a> Repository<'a> { Ok(()) } - fn calculate_version(source_path: &Path) -> Result, BakareError> { + fn calculate_version(source_path: &Path) -> Result { let source_file = File::open(source_path)?; let mut reader = BufReader::new(source_file); let mut hasher = Sha512::new(); io::copy(&mut reader, &mut hasher)?; - let version = hasher.result(); - Ok(Box::from(version.as_slice())) + Ok(hasher.result().as_slice().into()) } pub fn item_by_source_path(&self, path: &Path) -> Result, BakareError> { diff --git a/src/repository_item.rs b/src/repository_item.rs index 60e2a77..83cd3cc 100644 --- a/src/repository_item.rs +++ b/src/repository_item.rs @@ -1,4 +1,5 @@ use crate::error::BakareError; +use crate::index::ItemVersion; use std::fmt::{Display, Formatter}; use std::path::Path; use std::{fmt, fs}; @@ -8,11 +9,11 @@ pub struct RepositoryItem { relative_path: Box, absolute_path: Box, original_source_path: Box, - version: Box<[u8]>, + version: ItemVersion, } impl RepositoryItem { - pub fn from(original_source_path: &Path, absolute_path: &Path, relative_path: &Path, version: Box<[u8]>) -> Self { + pub fn from(original_source_path: &Path, absolute_path: &Path, relative_path: &Path, version: ItemVersion) -> Self { RepositoryItem { relative_path: Box::from(relative_path), absolute_path: Box::from(absolute_path), @@ -50,8 +51,8 @@ impl RepositoryItem { &self.original_source_path } - pub fn version(&self) -> Box<[u8]> { - self.version.clone() + pub fn version(&self) -> &ItemVersion { + &self.version } } diff --git a/src/restore.rs b/src/restore.rs index a582e31..346a966 100644 --- a/src/restore.rs +++ b/src/restore.rs @@ -1,6 +1,7 @@ use std::path::Path; use crate::error::BakareError; +use crate::index::ItemVersion; use crate::repository::Repository; use crate::repository_item::RepositoryItem; @@ -29,4 +30,9 @@ impl<'a> Engine<'a> { item.save(self.target_path)?; Ok(()) } + + pub fn restore_as_of_version(&self, item: &RepositoryItem, version: &ItemVersion) -> Result<(), BakareError> { + println!("restoring {}", item); + Ok(()) + } } diff --git a/tests/system_tests.rs b/tests/system_tests.rs index 37dd10b..7a8f99f 100644 --- a/tests/system_tests.rs +++ b/tests/system_tests.rs @@ -75,7 +75,7 @@ fn restore_older_version_of_file() -> Result<(), BakareError> { let item = reading_repository.item_by_source_path(&file_path)?; assert!(item.is_some()); let item = item.unwrap(); - let _old_version = item.version(); + let old_version = item.version(); { let new_contents = "totally new contents"; @@ -87,8 +87,8 @@ fn restore_older_version_of_file() -> Result<(), BakareError> { let restore_repository = Repository::open(repository_path.as_path())?; let restore_target = tempdir()?; - let _restore_engine = restore::Engine::new(&restore_repository, &restore_target.path())?; - //restore_engine.restore_as_of_version(&item, old_version)?; + let restore_engine = restore::Engine::new(&restore_repository, &restore_target.path())?; + restore_engine.restore_as_of_version(&item, old_version)?; assert_target_file_contents(restore_target.path(), relative_path_text, old_contents) } @@ -161,3 +161,5 @@ fn get_sorted_files_recursively(path: &Path) -> Result>, BakareErr } // TODO: restore latest version by default // TODO: deduplicate data +// TODO: test that index is stored separately from data +// TODO: index corruption