new code layout

This commit is contained in:
Cyryl Płotnicki 2019-01-26 19:27:23 +00:00
parent ee51ca16de
commit 916b537e17
5 changed files with 57 additions and 49 deletions

View file

@ -27,7 +27,7 @@ impl<'a> Engine<'a> {
for maybe_entry in walker {
let entry = maybe_entry?;
if entry.path() != self.source_path {
self.repository.store_entry(&entry)?;
self.repository.store(entry.path())?;
}
}
Ok(())

View file

@ -8,58 +8,61 @@ use walkdir::DirEntry;
use crate::error::BakareError;
use crate::Version;
/// represents a place where backup is stored an can be restored from. E.g. a directory, a cloud service etc
/// represents a place where backup is stored an can be restored from.
/// right now only on-disk directory storage is supported
pub struct Repository<'a> {
/// absolute path to where the repository is stored on disk
path: &'a Path,
}
pub struct StoredItemId;
pub struct RelativePath;
pub struct RepositoryItem {
version: Version
}
impl<'a> Iterator for &Repository<'a> {
type Item = RepositoryItem;
fn next(&mut self) -> Option<Self::Item> {
unimplemented!()
}
}
impl RepositoryItem {
pub fn version(&self) -> &Version {
&self.version
}
}
impl<'a> Repository<'a> {
pub fn new(path: &Path) -> Result<Repository, BakareError> {
Ok(Repository { path })
}
pub fn store_entry(&self, entry: &DirEntry) -> Result<(), BakareError> {
pub fn store(&self, source_path: &Path) -> Result<(), BakareError> {
// get file id -> contents hash + original path + time of taking notes
// get storage path for File
// store file contents
// remember File
if entry.file_type().is_dir() {
fs::create_dir(self.path.join(entry.file_name()))?;
if source_path.is_dir() {
fs::create_dir(self.path.join(source_path))?;
}
if entry.file_type().is_file() {
fs::copy(entry.path(), self.path.join(entry.file_name()))?;
if source_path.is_file() {
fs::copy(source_path, self.path.join(source_path))?;
}
// TODO create new version, remember source_path
Ok(())
}
pub fn newest_version_for(&self, item: &StoredItemId) -> Result<Version, BakareError> {
pub fn item(&self, path: &Path) -> Option<RepositoryItem> {
unimplemented!()
}
pub fn relative_path(&self, path: &str) -> RelativePath {
pub fn newest_version_for(&self, source_path: &Path) -> Result<Version, BakareError> {
unimplemented!()
}
pub fn file_id(&self, path: &RelativePath) -> Result<StoredItemId, BakareError> {
unimplemented!()
}
}
impl<'a> Iterator for Repository<'a> {
type Item = StoredItemId;
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
unimplemented!()
}
}
impl<'a> Iterator for &Repository<'a> {
type Item = StoredItemId;
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
unimplemented!()
}
}

View file

@ -8,8 +8,8 @@ use walkdir::WalkDir;
use crate::error::BakareError;
use crate::repository::Repository;
use crate::repository::StoredItemId;
use crate::Version;
use crate::repository::RepositoryItem;
pub struct Engine<'a> {
repository: &'a Repository<'a>,
@ -22,18 +22,17 @@ impl<'a> Engine<'a> {
}
pub fn restore_all(&self) -> Result<(), BakareError> {
for item in self.repository {
for ref item in self.repository {
self.restore(item)?;
}
Ok(())
}
fn restore(&self, item: StoredItemId) -> Result<(), BakareError> {
let version = self.repository.newest_version_for(&item)?;
self.restore_as_of_version(item, version)
fn restore(&self, item: &RepositoryItem) -> Result<(), BakareError> {
unimplemented!()
}
pub fn restore_as_of_version(&self, what: StoredItemId, version: Version) -> Result<(), BakareError> {
pub fn restore_as_of_version(&self, item: &RepositoryItem, version: &Version) -> Result<(), BakareError> {
unimplemented!()
}

View file

@ -5,21 +5,27 @@ use std::path::Path;
use tempfile::tempdir;
use tempfile::TempDir;
use std::path::PathBuf;
pub struct Source {
pub struct TempSource {
directory: TempDir,
}
impl Source {
impl TempSource {
pub fn new() -> Result<Self, Error> {
Ok(Self { directory: tempdir()? })
}
pub fn write_text_to_file(&self, filename: &str, text: &str) -> Result<(), Error> {
Ok(File::create(self.directory.path().join(filename))?.write_all(text.as_bytes())?)
let path = self.file_path(filename);
Ok(File::create(path)?.write_all(text.as_bytes())?)
}
pub fn path(&self) -> &Path {
self.directory.path()
}
pub fn file_path(&self, filename: &str) -> PathBuf {
self.directory.path().join(filename)
}
}

View file

@ -1,7 +1,7 @@
use bakare::backup;
use bakare::restore;
use bakare::source::Source;
use bakare::source::TempSource;
use bakare::error::BakareError;
use bakare::repository::Repository;
@ -13,7 +13,7 @@ use tempfile::tempdir;
#[test]
fn restore_backed_up_files() -> Result<(), BakareError> {
let source = Source::new()?;
let source = TempSource::new()?;
source.write_text_to_file("first", "some contents")?;
source.write_text_to_file("second", "some contents")?;
@ -24,28 +24,28 @@ fn restore_backed_up_files() -> Result<(), BakareError> {
#[test]
fn restore_older_version_of_file() -> Result<(), BakareError> {
let source = Source::new()?;
let source = TempSource::new()?;
let repository_path = tempdir()?.into_path();
let repository = Repository::new(repository_path.as_path())?;
let backup_engine = backup::Engine::new(source.path(), &repository);
let file_path = "some path";
let relative_path_text = "some path";
let file_path = source.file_path(relative_path_text);
let new_contents = "totally new contents";
let restore_target = tempdir()?;
let restore_engine = restore::Engine::new(&repository, &restore_target.path());
let old_contents = "some old contents";
source.write_text_to_file(file_path, old_contents)?;
source.write_text_to_file(relative_path_text, old_contents)?;
backup_engine.backup()?;
let repository_path = repository.relative_path(file_path);
let file_id = repository.file_id(&repository_path)?;
let old_version = repository.newest_version_for(&file_id)?;
let file_id = repository.item(&file_path).unwrap();
let old_version = file_id.version();
source.write_text_to_file(file_path, new_contents)?;
source.write_text_to_file(relative_path_text, new_contents)?;
backup_engine.backup()?;
restore_engine.restore_as_of_version(file_id, old_version)?;
restore_engine.restore_as_of_version(&file_id, old_version)?;
assert_target_file_contents(restore_target.path(), file_path, old_contents)
assert_target_file_contents(restore_target.path(), relative_path_text, old_contents)
}
fn assert_target_file_contents(target: &Path, filename: &str, expected_contents: &str) -> Result<(), BakareError> {