new code layout
This commit is contained in:
parent
ee51ca16de
commit
916b537e17
5 changed files with 57 additions and 49 deletions
|
@ -27,7 +27,7 @@ impl<'a> Engine<'a> {
|
||||||
for maybe_entry in walker {
|
for maybe_entry in walker {
|
||||||
let entry = maybe_entry?;
|
let entry = maybe_entry?;
|
||||||
if entry.path() != self.source_path {
|
if entry.path() != self.source_path {
|
||||||
self.repository.store_entry(&entry)?;
|
self.repository.store(entry.path())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -8,58 +8,61 @@ use walkdir::DirEntry;
|
||||||
use crate::error::BakareError;
|
use crate::error::BakareError;
|
||||||
use crate::Version;
|
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> {
|
pub struct Repository<'a> {
|
||||||
|
/// absolute path to where the repository is stored on disk
|
||||||
path: &'a Path,
|
path: &'a Path,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StoredItemId;
|
pub struct RepositoryItem {
|
||||||
pub struct RelativePath;
|
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> {
|
impl<'a> Repository<'a> {
|
||||||
pub fn new(path: &Path) -> Result<Repository, BakareError> {
|
pub fn new(path: &Path) -> Result<Repository, BakareError> {
|
||||||
Ok(Repository { path })
|
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 file id -> contents hash + original path + time of taking notes
|
||||||
// get storage path for File
|
// get storage path for File
|
||||||
// store file contents
|
// store file contents
|
||||||
// remember File
|
// remember File
|
||||||
|
|
||||||
if entry.file_type().is_dir() {
|
if source_path.is_dir() {
|
||||||
fs::create_dir(self.path.join(entry.file_name()))?;
|
fs::create_dir(self.path.join(source_path))?;
|
||||||
}
|
}
|
||||||
if entry.file_type().is_file() {
|
if source_path.is_file() {
|
||||||
fs::copy(entry.path(), self.path.join(entry.file_name()))?;
|
fs::copy(source_path, self.path.join(source_path))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO create new version, remember source_path
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn newest_version_for(&self, item: &StoredItemId) -> Result<Version, BakareError> {
|
pub fn item(&self, path: &Path) -> Option<RepositoryItem> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn relative_path(&self, path: &str) -> RelativePath {
|
pub fn newest_version_for(&self, source_path: &Path) -> Result<Version, BakareError> {
|
||||||
unimplemented!()
|
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!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,8 +8,8 @@ use walkdir::WalkDir;
|
||||||
|
|
||||||
use crate::error::BakareError;
|
use crate::error::BakareError;
|
||||||
use crate::repository::Repository;
|
use crate::repository::Repository;
|
||||||
use crate::repository::StoredItemId;
|
|
||||||
use crate::Version;
|
use crate::Version;
|
||||||
|
use crate::repository::RepositoryItem;
|
||||||
|
|
||||||
pub struct Engine<'a> {
|
pub struct Engine<'a> {
|
||||||
repository: &'a Repository<'a>,
|
repository: &'a Repository<'a>,
|
||||||
|
@ -22,18 +22,17 @@ impl<'a> Engine<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn restore_all(&self) -> Result<(), BakareError> {
|
pub fn restore_all(&self) -> Result<(), BakareError> {
|
||||||
for item in self.repository {
|
for ref item in self.repository {
|
||||||
self.restore(item)?;
|
self.restore(item)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn restore(&self, item: StoredItemId) -> Result<(), BakareError> {
|
fn restore(&self, item: &RepositoryItem) -> Result<(), BakareError> {
|
||||||
let version = self.repository.newest_version_for(&item)?;
|
unimplemented!()
|
||||||
self.restore_as_of_version(item, version)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,21 +5,27 @@ use std::path::Path;
|
||||||
|
|
||||||
use tempfile::tempdir;
|
use tempfile::tempdir;
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
pub struct Source {
|
pub struct TempSource {
|
||||||
directory: TempDir,
|
directory: TempDir,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Source {
|
impl TempSource {
|
||||||
pub fn new() -> Result<Self, Error> {
|
pub fn new() -> Result<Self, Error> {
|
||||||
Ok(Self { directory: tempdir()? })
|
Ok(Self { directory: tempdir()? })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_text_to_file(&self, filename: &str, text: &str) -> Result<(), Error> {
|
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 {
|
pub fn path(&self) -> &Path {
|
||||||
self.directory.path()
|
self.directory.path()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn file_path(&self, filename: &str) -> PathBuf {
|
||||||
|
self.directory.path().join(filename)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use bakare::backup;
|
use bakare::backup;
|
||||||
use bakare::restore;
|
use bakare::restore;
|
||||||
|
|
||||||
use bakare::source::Source;
|
use bakare::source::TempSource;
|
||||||
|
|
||||||
use bakare::error::BakareError;
|
use bakare::error::BakareError;
|
||||||
use bakare::repository::Repository;
|
use bakare::repository::Repository;
|
||||||
|
@ -13,7 +13,7 @@ use tempfile::tempdir;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn restore_backed_up_files() -> Result<(), BakareError> {
|
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("first", "some contents")?;
|
||||||
source.write_text_to_file("second", "some contents")?;
|
source.write_text_to_file("second", "some contents")?;
|
||||||
|
@ -24,28 +24,28 @@ fn restore_backed_up_files() -> Result<(), BakareError> {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn restore_older_version_of_file() -> Result<(), BakareError> {
|
fn restore_older_version_of_file() -> Result<(), BakareError> {
|
||||||
let source = Source::new()?;
|
let source = TempSource::new()?;
|
||||||
let repository_path = tempdir()?.into_path();
|
let repository_path = tempdir()?.into_path();
|
||||||
let repository = Repository::new(repository_path.as_path())?;
|
let repository = Repository::new(repository_path.as_path())?;
|
||||||
let backup_engine = backup::Engine::new(source.path(), &repository);
|
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 new_contents = "totally new contents";
|
||||||
let restore_target = tempdir()?;
|
let restore_target = tempdir()?;
|
||||||
let restore_engine = restore::Engine::new(&repository, &restore_target.path());
|
let restore_engine = restore::Engine::new(&repository, &restore_target.path());
|
||||||
let old_contents = "some old contents";
|
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()?;
|
backup_engine.backup()?;
|
||||||
let repository_path = repository.relative_path(file_path);
|
let file_id = repository.item(&file_path).unwrap();
|
||||||
let file_id = repository.file_id(&repository_path)?;
|
let old_version = file_id.version();
|
||||||
let old_version = repository.newest_version_for(&file_id)?;
|
|
||||||
|
|
||||||
source.write_text_to_file(file_path, new_contents)?;
|
source.write_text_to_file(relative_path_text, new_contents)?;
|
||||||
backup_engine.backup()?;
|
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> {
|
fn assert_target_file_contents(target: &Path, filename: &str, expected_contents: &str) -> Result<(), BakareError> {
|
||||||
|
|
Loading…
Reference in a new issue