diff --git a/crates/rustic_core/examples/check.rs b/crates/rustic_core/examples/check.rs
index 44a603620..3488012ae 100644
--- a/crates/rustic_core/examples/check.rs
+++ b/crates/rustic_core/examples/check.rs
@@ -7,9 +7,11 @@ fn main() {
let _ = SimpleLogger::init(LevelFilter::Info, Config::default());
// Open repository
- let mut repo_opts = RepositoryOptions::default();
- repo_opts.repository = Some("/tmp/repo".to_string());
- repo_opts.password = Some("test".to_string());
+ let repo_opts = RepositoryOptions {
+ repository: Some("/tmp/repo".to_string()),
+ password: Some("test".to_string()),
+ ..Default::default()
+ };
let repo = Repository::new(&repo_opts).unwrap().open().unwrap();
// Check respository with standard options
diff --git a/crates/rustic_core/examples/forget.rs b/crates/rustic_core/examples/forget.rs
index e9d197642..3ecd022a0 100644
--- a/crates/rustic_core/examples/forget.rs
+++ b/crates/rustic_core/examples/forget.rs
@@ -7,9 +7,11 @@ fn main() {
let _ = SimpleLogger::init(LevelFilter::Info, Config::default());
// Open repository
- let mut repo_opts = RepositoryOptions::default();
- repo_opts.repository = Some("/tmp/repo".to_string());
- repo_opts.password = Some("test".to_string());
+ let repo_opts = RepositoryOptions {
+ repository: Some("/tmp/repo".to_string()),
+ password: Some("test".to_string()),
+ ..Default::default()
+ };
let repo = Repository::new(&repo_opts).unwrap().open().unwrap();
// Check respository with standard options
diff --git a/crates/rustic_core/examples/prune.rs b/crates/rustic_core/examples/prune.rs
index 7100e2725..34b6ec0aa 100644
--- a/crates/rustic_core/examples/prune.rs
+++ b/crates/rustic_core/examples/prune.rs
@@ -7,9 +7,11 @@ fn main() {
let _ = SimpleLogger::init(LevelFilter::Info, Config::default());
// Open repository
- let mut repo_opts = RepositoryOptions::default();
- repo_opts.repository = Some("/tmp/repo".to_string());
- repo_opts.password = Some("test".to_string());
+ let repo_opts = RepositoryOptions {
+ repository: Some("/tmp/repo".to_string()),
+ password: Some("test".to_string()),
+ ..Default::default()
+ };
let repo = Repository::new(&repo_opts).unwrap().open().unwrap();
let prune_opts = PruneOpts::default();
diff --git a/crates/rustic_core/src/commands/cat.rs b/crates/rustic_core/src/commands/cat.rs
index 644afc175..bfd9e852d 100644
--- a/crates/rustic_core/src/commands/cat.rs
+++ b/crates/rustic_core/src/commands/cat.rs
@@ -3,40 +3,49 @@ use std::path::Path;
use bytes::Bytes;
use crate::{
- error::CommandErrorKind, repository::IndexedRepository, BlobType, DecryptReadBackend, FileType,
- Id, IndexedBackend, OpenRepository, ProgressBars, ReadBackend, RusticResult, SnapshotFile,
- Tree,
+ error::CommandErrorKind,
+ repository::{Indexed, Open, Repository},
+ BlobType, DecryptReadBackend, FileType, Id, IndexedBackend, ProgressBars, ReadBackend,
+ RusticResult, SnapshotFile, Tree,
};
-pub fn cat_file
(repo: &OpenRepository
, tpe: FileType, id: &str) -> RusticResult {
- let id = repo.dbe.find_id(tpe, id)?;
- let data = repo.dbe.read_encrypted_full(tpe, &id)?;
+pub(crate) fn cat_file(
+ repo: &Repository
,
+ tpe: FileType,
+ id: &str,
+) -> RusticResult {
+ let id = repo.dbe().find_id(tpe, id)?;
+ let data = repo.dbe().read_encrypted_full(tpe, &id)?;
Ok(data)
}
-pub fn cat_blob(repo: &IndexedRepository
, tpe: BlobType, id: &str) -> RusticResult {
+pub(crate) fn cat_blob(
+ repo: &Repository
,
+ tpe: BlobType,
+ id: &str,
+) -> RusticResult {
let id = Id::from_hex(id)?;
- let data = repo.index.blob_from_backend(tpe, &id)?;
+ let data = repo.index().blob_from_backend(tpe, &id)?;
Ok(data)
}
-pub fn cat_tree(
- repo: &IndexedRepository,
+pub(crate) fn cat_tree(
+ repo: &Repository,
snap: &str,
sn_filter: impl FnMut(&SnapshotFile) -> bool + Send + Sync,
) -> RusticResult {
let (id, path) = snap.split_once(':').unwrap_or((snap, ""));
let snap = SnapshotFile::from_str(
- &repo.repo.dbe,
+ repo.dbe(),
id,
sn_filter,
- &repo.repo.pb.progress_counter("getting snapshot..."),
+ &repo.pb.progress_counter("getting snapshot..."),
)?;
- let node = Tree::node_from_path(&repo.index, snap.tree, Path::new(path))?;
+ let node = Tree::node_from_path(repo.index(), snap.tree, Path::new(path))?;
let id = node
.subtree
.ok_or_else(|| CommandErrorKind::PathIsNoDir(path.to_string()))?;
- let data = repo.index.blob_from_backend(BlobType::Tree, &id)?;
+ let data = repo.index().blob_from_backend(BlobType::Tree, &id)?;
Ok(data)
}
diff --git a/crates/rustic_core/src/commands/check.rs b/crates/rustic_core/src/commands/check.rs
index 13977a76b..d7c624ad6 100644
--- a/crates/rustic_core/src/commands/check.rs
+++ b/crates/rustic_core/src/commands/check.rs
@@ -8,10 +8,12 @@ use rayon::prelude::{IntoParallelIterator, ParallelBridge, ParallelIterator};
use zstd::stream::decode_all;
use crate::{
- hash, progress::ProgressBars, BlobType, Cache, DecryptReadBackend, FileType, Id, IndexBackend,
- IndexCollector, IndexFile, IndexPack, IndexType, IndexedBackend, NodeType, OpenRepository,
- PackHeader, PackHeaderLength, PackHeaderRef, Progress, ReadBackend, RusticResult, SnapshotFile,
- TreeStreamerOnce,
+ hash,
+ progress::ProgressBars,
+ repository::{Open, Repository},
+ BlobType, Cache, DecryptReadBackend, FileType, Id, IndexBackend, IndexCollector, IndexFile,
+ IndexPack, IndexType, IndexedBackend, NodeType, PackHeader, PackHeaderLength, PackHeaderRef,
+ Progress, ReadBackend, RusticResult, SnapshotFile, TreeStreamerOnce,
};
/// `check` subcommand
@@ -28,9 +30,9 @@ pub struct CheckOpts {
}
impl CheckOpts {
- pub fn run(self, repo: &OpenRepository) -> RusticResult<()> {
- let be = &repo.dbe;
- let cache = &repo.cache;
+ pub(crate) fn run(self, repo: &Repository) -> RusticResult<()> {
+ let be = repo.dbe();
+ let cache = repo.cache();
let hot_be = &repo.be_hot;
let raw_be = &repo.be;
let pb = &repo.pb;
diff --git a/crates/rustic_core/src/commands/dump.rs b/crates/rustic_core/src/commands/dump.rs
index 374f24f57..fd499b38e 100644
--- a/crates/rustic_core/src/commands/dump.rs
+++ b/crates/rustic_core/src/commands/dump.rs
@@ -1,12 +1,13 @@
use std::io::Write;
use crate::{
- error::CommandErrorKind, repository::IndexedRepository, BlobType, IndexedBackend, Node,
- NodeType, RusticResult,
+ error::CommandErrorKind,
+ repository::{Indexed, Repository},
+ BlobType, IndexedBackend, Node, NodeType, RusticResult,
};
-pub(crate) fn dump
(
- repo: &IndexedRepository
,
+pub(crate) fn dump
(
+ repo: &Repository
,
node: &Node,
w: &mut impl Write,
) -> RusticResult<()> {
@@ -16,7 +17,7 @@ pub(crate) fn dump
(
for id in node.content.as_ref().unwrap() {
// TODO: cache blobs which are needed later
- let data = repo.index.blob_from_backend(BlobType::Data, id)?;
+ let data = repo.index().blob_from_backend(BlobType::Data, id)?;
w.write_all(&data)?;
}
Ok(())
diff --git a/crates/rustic_core/src/commands/forget.rs b/crates/rustic_core/src/commands/forget.rs
index aaeba767a..76eb27a69 100644
--- a/crates/rustic_core/src/commands/forget.rs
+++ b/crates/rustic_core/src/commands/forget.rs
@@ -6,7 +6,7 @@ use serde::Deserialize;
use serde_with::{serde_as, DisplayFromStr};
use crate::{
- Id, OpenRepository, ProgressBars, RusticResult, SnapshotFile, SnapshotGroup,
+ repository::Open, Id, ProgressBars, Repository, RusticResult, SnapshotFile, SnapshotGroup,
SnapshotGroupCriterion, StringList,
};
@@ -41,8 +41,8 @@ impl ForgetGroups {
}
}
-pub(crate) fn get_forget_snapshots(
- repo: &OpenRepository,
+pub(crate) fn get_forget_snapshots(
+ repo: &Repository,
keep: &KeepOptions,
group_by: SnapshotGroupCriterion,
filter: impl FnMut(&SnapshotFile) -> bool,
diff --git a/crates/rustic_core/src/commands/prune.rs b/crates/rustic_core/src/commands/prune.rs
index bfaa53cd9..bffa5bea9 100644
--- a/crates/rustic_core/src/commands/prune.rs
+++ b/crates/rustic_core/src/commands/prune.rs
@@ -19,11 +19,11 @@ use itertools::Itertools;
use rayon::prelude::{IntoParallelIterator, ParallelIterator};
use crate::{
- error::CommandErrorKind, BlobType, BlobTypeMap, DecryptReadBackend, DecryptWriteBackend,
- FileType, HeaderEntry, Id, IndexBackend, IndexBlob, IndexCollector, IndexFile, IndexPack,
- IndexType, IndexedBackend, Indexer, Initialize, NodeType, OpenRepository, PackSizer, Progress,
- ProgressBars, ReadBackend, ReadIndex, Repacker, RusticResult, SnapshotFile, Sum,
- TreeStreamerOnce,
+ error::CommandErrorKind, repository::Open, BlobType, BlobTypeMap, DecryptReadBackend,
+ DecryptWriteBackend, FileType, HeaderEntry, Id, IndexBackend, IndexBlob, IndexCollector,
+ IndexFile, IndexPack, IndexType, IndexedBackend, Indexer, Initialize, NodeType, PackSizer,
+ Progress, ProgressBars, ReadBackend, ReadIndex, Repacker, Repository, RusticResult,
+ SnapshotFile, Sum, TreeStreamerOnce,
};
pub(super) mod constants {
@@ -115,11 +115,14 @@ impl Default for PruneOpts {
}
impl PruneOpts {
- pub fn get_plan(&self, repo: &OpenRepository) -> RusticResult {
+ pub fn get_plan(
+ &self,
+ repo: &Repository,
+ ) -> RusticResult {
let pb = &repo.pb;
- let be = &repo.dbe;
+ let be = repo.dbe();
- if repo.config.version < 2 && self.repack_uncompressed {
+ if repo.config().version < 2 && self.repack_uncompressed {
return Err(CommandErrorKind::RepackUncompressedRepoV1.into());
}
@@ -158,9 +161,9 @@ impl PruneOpts {
pruner.check()?;
let repack_cacheable_only = self
.repack_cacheable_only
- .unwrap_or_else(|| repo.config.is_hot == Some(true));
+ .unwrap_or_else(|| repo.config().is_hot == Some(true));
let pack_sizer =
- total_size.map(|tpe, size| PackSizer::from_config(&repo.config, tpe, size));
+ total_size.map(|tpe, size| PackSizer::from_config(repo.config(), tpe, size));
pruner.decide_packs(
Duration::from_std(*self.keep_pack).map_err(CommandErrorKind::FromOutOfRangeError)?,
Duration::from_std(*self.keep_delete).map_err(CommandErrorKind::FromOutOfRangeError)?,
@@ -745,13 +748,13 @@ impl PrunePlan {
}
#[allow(clippy::significant_drop_tightening)]
- pub fn do_prune(
+ pub fn do_prune(
self,
- repo: &OpenRepository,
+ repo: &Repository
,
opts: &PruneOpts,
) -> RusticResult<()> {
repo.warm_up_wait(self.repack_packs().into_iter())?;
- let be = &repo.dbe;
+ let be = repo.dbe();
let pb = &repo.pb;
let indexer = Indexer::new_unindexed(be.clone()).into_shared();
@@ -776,7 +779,7 @@ impl PrunePlan {
be.clone(),
BlobType::Tree,
indexer.clone(),
- &repo.config,
+ repo.config(),
size_after_prune[BlobType::Tree],
)?;
@@ -784,7 +787,7 @@ impl PrunePlan {
be.clone(),
BlobType::Data,
indexer.clone(),
- &repo.config,
+ repo.config(),
size_after_prune[BlobType::Data],
)?;
@@ -1050,7 +1053,7 @@ impl PackInfo {
// find used blobs in repo
fn find_used_blobs(
- index: &(impl IndexedBackend + Unpin),
+ index: &impl IndexedBackend,
ignore_snaps: &[Id],
pb: &impl ProgressBars,
) -> RusticResult> {
diff --git a/crates/rustic_core/src/commands/repoinfo.rs b/crates/rustic_core/src/commands/repoinfo.rs
index 3d4197e02..b8117bed1 100644
--- a/crates/rustic_core/src/commands/repoinfo.rs
+++ b/crates/rustic_core/src/commands/repoinfo.rs
@@ -3,8 +3,9 @@ use serde::{Deserialize, Serialize};
use crate::{
index::IndexEntry,
repofile::indexfile::{IndexFile, IndexPack},
- BlobType, BlobTypeMap, DecryptReadBackend, FileType, OpenRepository, Progress, ProgressBars,
- ReadBackend, Repository, RusticResult, ALL_FILE_TYPES,
+ repository::Open,
+ BlobType, BlobTypeMap, DecryptReadBackend, FileType, Progress, ProgressBars, ReadBackend,
+ Repository, RusticResult, ALL_FILE_TYPES,
};
#[derive(Default, Clone, Debug, Serialize, Deserialize)]
@@ -53,8 +54,8 @@ impl PackInfo {
}
}
-pub(crate) fn collect_index_infos(
- repo: &OpenRepository,
+pub(crate) fn collect_index_infos(
+ repo: &Repository,
) -> RusticResult {
let mut blob_info = BlobTypeMap::<()>::default().map(|blob_type, _| BlobInfo {
blob_type,
@@ -72,7 +73,7 @@ pub(crate) fn collect_index_infos(
let mut pack_info_delete = pack_info;
let p = repo.pb.progress_counter("scanning index...");
- for index in repo.dbe.stream_all::(&p)? {
+ for index in repo.dbe().stream_all::(&p)? {
let index = index?.1;
for pack in &index.packs {
let tpe = pack.blob_type();
@@ -130,7 +131,9 @@ pub(crate) fn collect_file_info(be: &impl ReadBackend) -> RusticResult(repo: &Repository) -> RusticResult {
+pub fn collect_file_infos(
+ repo: &Repository,
+) -> RusticResult {
let p = repo.pb.progress_spinner("scanning files...");
let files = collect_file_info(&repo.be)?;
let files_hot = repo.be_hot.as_ref().map(collect_file_info).transpose()?;
diff --git a/crates/rustic_core/src/commands/snapshots.rs b/crates/rustic_core/src/commands/snapshots.rs
index 3d9211be1..58b3925a0 100644
--- a/crates/rustic_core/src/commands/snapshots.rs
+++ b/crates/rustic_core/src/commands/snapshots.rs
@@ -1,35 +1,35 @@
//! `smapshot` subcommand
use crate::{
- OpenRepository, ProgressBars, RusticResult, SnapshotFile, SnapshotGroup, SnapshotGroupCriterion,
+ repository::Open, ProgressBars, Repository, RusticResult, SnapshotFile, SnapshotGroup,
+ SnapshotGroupCriterion,
};
-pub(crate) fn get_snapshot_group(
- repo: &OpenRepository,
+pub(crate) fn get_snapshot_group(
+ repo: &Repository,
ids: &[String],
group_by: SnapshotGroupCriterion,
filter: impl FnMut(&SnapshotFile) -> bool,
) -> RusticResult)>> {
let pb = &repo.pb;
+ let dbe = repo.dbe();
let p = pb.progress_counter("getting snapshots...");
let groups = match ids {
- [] => SnapshotFile::group_from_backend(&repo.dbe, filter, group_by, &p)?,
- [id] if id == "latest" => {
- SnapshotFile::group_from_backend(&repo.dbe, filter, group_by, &p)?
- .into_iter()
- .map(|(group, mut snaps)| {
- snaps.sort_unstable();
- let last_idx = snaps.len() - 1;
- snaps.swap(0, last_idx);
- snaps.truncate(1);
- (group, snaps)
- })
- .collect::>()
- }
+ [] => SnapshotFile::group_from_backend(dbe, filter, group_by, &p)?,
+ [id] if id == "latest" => SnapshotFile::group_from_backend(dbe, filter, group_by, &p)?
+ .into_iter()
+ .map(|(group, mut snaps)| {
+ snaps.sort_unstable();
+ let last_idx = snaps.len() - 1;
+ snaps.swap(0, last_idx);
+ snaps.truncate(1);
+ (group, snaps)
+ })
+ .collect::>(),
_ => {
let item = (
SnapshotGroup::default(),
- SnapshotFile::from_ids(&repo.dbe, ids, &p)?,
+ SnapshotFile::from_ids(dbe, ids, &p)?,
);
vec![item]
}
diff --git a/crates/rustic_core/src/lib.rs b/crates/rustic_core/src/lib.rs
index 72ed03617..a87674771 100644
--- a/crates/rustic_core/src/lib.rs
+++ b/crates/rustic_core/src/lib.rs
@@ -147,5 +147,5 @@ pub use crate::{
},
RepoFile,
},
- repository::{read_password_from_reader, OpenRepository, Repository, RepositoryOptions},
+ repository::{read_password_from_reader, Open, OpenStatus, Repository, RepositoryOptions},
};
diff --git a/crates/rustic_core/src/repository.rs b/crates/rustic_core/src/repository.rs
index 4080ee1ce..3e7155256 100644
--- a/crates/rustic_core/src/repository.rs
+++ b/crates/rustic_core/src/repository.rs
@@ -37,8 +37,9 @@ use crate::{
crypto::aespoly1305::Key,
error::RepositoryErrorKind,
repofile::{configfile::ConfigFile, keyfile::find_key_in_backend},
- BlobType, Id, IndexBackend, NoProgressBars, Node, ProgressBars, PruneOpts, PrunePlan,
- RusticResult, SnapshotFile, SnapshotGroup, SnapshotGroupCriterion, Tree,
+ BlobType, DecryptFullBackend, Id, IndexBackend, IndexedBackend, NoProgressBars, Node,
+ ProgressBars, PruneOpts, PrunePlan, RusticResult, SnapshotFile, SnapshotGroup,
+ SnapshotGroupCriterion, Tree,
};
pub(super) mod constants {
@@ -176,21 +177,22 @@ pub fn read_password_from_reader(file: &mut impl BufRead) -> RusticResult {
+pub struct Repository {
name: String,
pub be: HotColdBackend,
pub be_hot: Option,
opts: RepositoryOptions,
pub(crate) pb: P,
+ status: S,
}
-impl Repository {
+impl Repository {
pub fn new(opts: &RepositoryOptions) -> RusticResult {
Self::new_with_progress(opts, NoProgressBars {})
}
}
-impl Repository
{
+impl
Repository
{
pub fn new_with_progress(opts: &RepositoryOptions, pb: P) -> RusticResult {
let be = match &opts.repository {
Some(repo) => ChooseBackend::from_url(repo)?,
@@ -226,6 +228,7 @@ impl Repository
{
be_hot,
opts: opts.clone(),
pb,
+ status: (),
})
}
@@ -276,11 +279,11 @@ impl
Repository
{
}
}
- pub fn open(self) -> RusticResult> {
- let config_ids = match self.be.list(FileType::Config) {
- Ok(val) => val,
- Err(_e) => return Err(RepositoryErrorKind::ListingRepositoryConfigFileFailed.into()),
- };
+ pub fn open(self) -> RusticResult> {
+ let config_ids = self
+ .be
+ .list(FileType::Config)
+ .map_err(|_| RepositoryErrorKind::ListingRepositoryConfigFileFailed)?;
match config_ids.len() {
1 => {} // ok, continue
@@ -320,24 +323,35 @@ impl Repository
{
let zstd = config.zstd()?;
dbe.set_zstd(zstd);
- Ok(OpenRepository {
- name: self.name,
+ let open = OpenStatus {
key,
dbe,
cache,
+ config,
+ };
+
+ Ok(Repository {
+ name: self.name,
be: self.be,
be_hot: self.be_hot,
- config,
opts: self.opts,
pb: self.pb,
+ status: open,
})
}
}
-impl Repository {
+impl Repository {
pub fn infos_files(&self) -> RusticResult {
commands::repoinfo::collect_file_infos(self)
}
+ pub fn warm_up(&self, packs: impl ExactSizeIterator- ) -> RusticResult<()> {
+ warm_up(self, packs)
+ }
+
+ pub fn warm_up_wait(&self, packs: impl ExactSizeIterator
- ) -> RusticResult<()> {
+ warm_up_wait(self, packs)
+ }
}
pub(crate) fn get_key(be: &impl ReadBackend, password: Option) -> RusticResult {
@@ -366,20 +380,56 @@ pub(crate) fn get_key(be: &impl ReadBackend, password: Option) -> Rustic
Err(RepositoryErrorKind::IncorrectPassword.into())
}
+pub trait Open {
+ type DBE: DecryptFullBackend;
+ fn key(&self) -> &Key;
+ fn cache(&self) -> Option<&Cache>;
+ fn dbe(&self) -> &Self::DBE;
+ fn config(&self) -> &ConfigFile;
+}
+
+impl
Open for Repository
{
+ type DBE = S::DBE;
+ fn key(&self) -> &Key {
+ self.status.key()
+ }
+ fn cache(&self) -> Option<&Cache> {
+ self.status.cache()
+ }
+ fn dbe(&self) -> &Self::DBE {
+ self.status.dbe()
+ }
+ fn config(&self) -> &ConfigFile {
+ self.status.config()
+ }
+}
+
#[derive(Debug)]
-pub struct OpenRepository
{
- pub name: String,
- pub be: HotColdBackend,
- pub be_hot: Option,
- pub key: Key,
- pub cache: Option,
- pub dbe: DecryptBackend>, Key>,
- pub config: ConfigFile,
- pub opts: RepositoryOptions,
- pub(crate) pb: P,
+pub struct OpenStatus {
+ key: Key,
+ cache: Option,
+ dbe: DecryptBackend>, Key>,
+ config: ConfigFile,
}
-impl OpenRepository {
+impl Open for OpenStatus {
+ type DBE = DecryptBackend>, Key>;
+
+ fn key(&self) -> &Key {
+ &self.key
+ }
+ fn cache(&self) -> Option<&Cache> {
+ self.cache.as_ref()
+ }
+ fn dbe(&self) -> &Self::DBE {
+ &self.dbe
+ }
+ fn config(&self) -> &ConfigFile {
+ &self.config
+ }
+}
+
+impl Repository {
pub fn get_snapshot_group(
&self,
ids: &[String],
@@ -391,7 +441,7 @@ impl OpenRepository {
pub fn get_snapshots(&self, ids: &[String]) -> RusticResult> {
let p = self.pb.progress_counter("getting snapshots...");
- SnapshotFile::from_ids(&self.dbe, ids, &p)
+ SnapshotFile::from_ids(self.dbe(), ids, &p)
}
pub fn get_forget_snapshots(
@@ -405,7 +455,7 @@ impl OpenRepository {
pub fn delete_snapshots(&self, ids: &[Id]) -> RusticResult<()> {
let p = self.pb.progress_counter("removing snapshots...");
- self.dbe
+ self.dbe()
.delete_list(FileType::Snapshot, true, ids.iter(), p)?;
Ok(())
}
@@ -422,32 +472,71 @@ impl OpenRepository {
opts.get_plan(self)
}
- pub fn to_indexed(self) -> RusticResult> {
- let index = IndexBackend::new(&self.dbe, &self.pb.progress_counter(""))?;
- Ok(IndexedRepository { repo: self, index })
+ pub fn to_indexed(self) -> RusticResult>> {
+ let index = IndexBackend::new(self.dbe(), &self.pb.progress_counter(""))?;
+ let status = IndexedStatus {
+ open: self.status,
+ index,
+ };
+ Ok(Repository {
+ name: self.name,
+ be: self.be,
+ be_hot: self.be_hot,
+ opts: self.opts,
+ pb: self.pb,
+ status,
+ })
}
pub fn infos_index(&self) -> RusticResult {
commands::repoinfo::collect_index_infos(self)
}
+}
- pub fn warm_up(&self, packs: impl ExactSizeIterator- ) -> RusticResult<()> {
- warm_up(self, packs)
- }
+pub trait Indexed: Open {
+ type I: IndexedBackend;
+ fn index(&self) -> &Self::I;
+}
- pub fn warm_up_wait(&self, packs: impl ExactSizeIterator
- ) -> RusticResult<()> {
- warm_up_wait(self, packs)
+impl
Indexed for Repository
{
+ type I = S::I;
+ fn index(&self) -> &Self::I {
+ self.status.index()
}
}
#[derive(Debug)]
-pub struct IndexedRepository
{
- pub(crate) repo: OpenRepository
,
- pub(crate) index:
- IndexBackend>, Key>>,
+pub struct IndexedStatus {
+ open: S,
+ index: IndexBackend,
+}
+
+impl Indexed for IndexedStatus {
+ type I = IndexBackend;
+
+ fn index(&self) -> &Self::I {
+ &self.index
+ }
+}
+
+impl Open for IndexedStatus {
+ type DBE = S::DBE;
+
+ fn key(&self) -> &Key {
+ self.open.key()
+ }
+ fn cache(&self) -> Option<&Cache> {
+ self.open.cache()
+ }
+ fn dbe(&self) -> &Self::DBE {
+ self.open.dbe()
+ }
+ fn config(&self) -> &ConfigFile {
+ self.open.config()
+ }
}
-impl IndexedRepository {
+impl Repository {
pub fn node_from_snapshot_path(
&self,
snap_path: &str,
@@ -455,10 +544,10 @@ impl IndexedRepository {
) -> RusticResult {
let (id, path) = snap_path.split_once(':').unwrap_or((snap_path, ""));
- let p = &self.repo.pb.progress_counter("getting snapshot...");
- let snap = SnapshotFile::from_str(&self.repo.dbe, id, filter, p)?;
+ let p = &self.pb.progress_counter("getting snapshot...");
+ let snap = SnapshotFile::from_str(self.dbe(), id, filter, p)?;
- Tree::node_from_path(&self.index, snap.tree, Path::new(path))
+ Tree::node_from_path(self.index(), snap.tree, Path::new(path))
}
pub fn cat_blob(&self, tpe: BlobType, id: &str) -> RusticResult {
diff --git a/crates/rustic_core/src/repository/warm_up.rs b/crates/rustic_core/src/repository/warm_up.rs
index 433005cd0..7c70ca020 100644
--- a/crates/rustic_core/src/repository/warm_up.rs
+++ b/crates/rustic_core/src/repository/warm_up.rs
@@ -6,7 +6,7 @@ use rayon::ThreadPoolBuilder;
use super::parse_command;
use crate::{
- error::RepositoryErrorKind, FileType, Id, OpenRepository, Progress, ProgressBars, ReadBackend,
+ error::RepositoryErrorKind, FileType, Id, Progress, ProgressBars, ReadBackend, Repository,
RusticResult,
};
@@ -14,8 +14,8 @@ pub(super) mod constants {
pub(super) const MAX_READER_THREADS_NUM: usize = 20;
}
-pub(crate) fn warm_up_wait(
- repo: &OpenRepository,
+pub(crate) fn warm_up_wait(
+ repo: &Repository,
packs: impl ExactSizeIterator- ,
) -> RusticResult<()> {
warm_up(repo, packs)?;
@@ -27,8 +27,8 @@ pub(crate) fn warm_up_wait(
Ok(())
}
-pub(crate) fn warm_up(
- repo: &OpenRepository
,
+pub(crate) fn warm_up(
+ repo: &Repository,
packs: impl ExactSizeIterator- ,
) -> RusticResult<()> {
if let Some(command) = &repo.opts.warm_up_command {
@@ -61,8 +61,8 @@ fn warm_up_command(
Ok(())
}
-fn warm_up_access(
- repo: &OpenRepository
,
+fn warm_up_access(
+ repo: &Repository,
packs: impl ExactSizeIterator- ,
) -> RusticResult<()> {
let mut be = repo.be.clone();
diff --git a/src/commands.rs b/src/commands.rs
index 731284c52..26f0b045a 100644
--- a/src/commands.rs
+++ b/src/commands.rs
@@ -41,7 +41,7 @@ use crate::{
use abscissa_core::{
config::Override, status_err, Command, Configurable, FrameworkError, Runnable, Shutdown,
};
-use rustic_core::{OpenRepository, Repository};
+use rustic_core::{OpenStatus, Repository};
/// Rustic Subcommands
/// Subcommands need to be listed in an enum.
@@ -167,7 +167,7 @@ impl Configurable for EntryPoint {
}
}
-fn open_repository
(repo: Repository
) -> OpenRepository
{
+fn open_repository
(repo: Repository
) -> Repository
{
match repo.open() {
Ok(it) => it,
Err(err) => {
@@ -177,7 +177,7 @@ fn open_repository
(repo: Repository
) -> OpenRepository
{
}
}
-fn get_repository(config: &Arc) -> Repository {
+fn get_repository(config: &Arc) -> Repository {
let po = config.global.progress_options;
match Repository::new_with_progress(&config.repository, po) {
Ok(it) => it,
diff --git a/src/commands/backup.rs b/src/commands/backup.rs
index 26293087b..6a81ea0d7 100644
--- a/src/commands/backup.rs
+++ b/src/commands/backup.rs
@@ -22,7 +22,7 @@ use serde::Deserialize;
use rustic_core::{
Archiver, DryRunBackend, IndexBackend, LocalSource, LocalSourceFilterOptions,
- LocalSourceSaveOptions, PathList, ProgressBars, SnapshotFile, SnapshotGroup,
+ LocalSourceSaveOptions, Open, PathList, ProgressBars, SnapshotFile, SnapshotGroup,
SnapshotGroupCriterion, SnapshotOptions, StdinSource,
};
@@ -196,7 +196,7 @@ impl BackupCmd {
};
let index =
- IndexBackend::only_full_trees(&repo.dbe, &progress_options.progress_counter(""))?;
+ IndexBackend::only_full_trees(repo.dbe(), &progress_options.progress_counter(""))?;
for source in sources {
let mut opts = self.clone();
@@ -230,7 +230,7 @@ impl BackupCmd {
// merge "backup" section from config file, if given
opts.merge(config.backup.clone());
- let be = DryRunBackend::new(repo.dbe.clone(), config.global.dry_run);
+ let be = DryRunBackend::new(repo.dbe().clone(), config.global.dry_run);
info!("starting to backup {source}...");
let as_path = opts.as_path.map(|p| {
match p.parse_dot() {
@@ -283,7 +283,7 @@ impl BackupCmd {
let archiver = Archiver::new(
be,
index,
- &repo.config,
+ repo.config(),
parent_tree,
opts.ignore_ctime,
opts.ignore_inode,
diff --git a/src/commands/config.rs b/src/commands/config.rs
index b8c811c2d..3e13d008e 100644
--- a/src/commands/config.rs
+++ b/src/commands/config.rs
@@ -12,7 +12,7 @@ use abscissa_core::{Command, Runnable, Shutdown};
use anyhow::{bail, Result};
use bytesize::ByteSize;
-use rustic_core::{ConfigFile, DecryptBackend, DecryptWriteBackend};
+use rustic_core::{ConfigFile, DecryptBackend, DecryptWriteBackend, Open};
/// `config` subcommand
#[derive(clap::Parser, Command, Debug)]
@@ -33,23 +33,24 @@ impl Runnable for ConfigCmd {
impl ConfigCmd {
fn inner_run(&self) -> Result<()> {
let config = RUSTIC_APP.config();
- let mut repo = open_repository(get_repository(&config));
+ let repo = open_repository(get_repository(&config));
- let mut new_config = repo.config.clone();
+ let mut new_config = repo.config().clone();
self.config_opts.apply(&mut new_config)?;
- if new_config == repo.config {
+ if &new_config == repo.config() {
println!("config is unchanged");
} else {
new_config.is_hot = None;
// don't compress the config file
- repo.dbe.set_zstd(None);
+ let mut dbe = repo.dbe().clone();
+ dbe.set_zstd(None);
// for hot/cold backend, this only saves the config to the cold repo.
- _ = repo.dbe.save_file(&new_config)?;
+ _ = dbe.save_file(&new_config)?;
- if let Some(hot_be) = repo.be_hot {
+ if let Some(hot_be) = repo.be_hot.clone() {
// save config to hot repo
- let mut dbe = DecryptBackend::new(&hot_be, repo.key);
+ let mut dbe = DecryptBackend::new(&hot_be, *repo.key());
// don't compress the config file
dbe.set_zstd(None);
new_config.is_hot = Some(true);
diff --git a/src/commands/copy.rs b/src/commands/copy.rs
index 0ff7cee51..32380bacf 100644
--- a/src/commands/copy.rs
+++ b/src/commands/copy.rs
@@ -16,7 +16,7 @@ use serde::Deserialize;
use crate::commands::key::KeyOpts;
use rustic_core::{
- FileType, Id, IndexBackend, ProgressBars, ReadBackend, Repository, RepositoryOptions,
+ FileType, Id, IndexBackend, Open, ProgressBars, ReadBackend, Repository, RepositoryOptions,
SnapshotFile,
};
@@ -61,7 +61,7 @@ impl CopyCmd {
RUSTIC_APP.shutdown(Shutdown::Crash);
}
- let be = &repo.dbe;
+ let be = repo.dbe();
let p = config.global.progress_options.progress_hidden();
let mut snapshots = if self.ids.is_empty() {
SnapshotFile::all_from_backend(be, |sn| config.snapshot_filter.matches(sn), &p)?
@@ -71,16 +71,15 @@ impl CopyCmd {
// sort for nicer output
snapshots.sort_unstable();
- let be = &repo.dbe;
let index = IndexBackend::new(be, &config.global.progress_options.progress_counter(""))?;
- let poly = repo.config.poly()?;
+ let poly = repo.config().poly()?;
for target_opt in &config.copy.targets {
let repo_dest = Repository::new(target_opt)?;
if self.init && repo_dest.be.list(FileType::Config)?.is_empty() {
- let mut config_dest = repo.config.clone();
+ let mut config_dest = repo.config().clone();
config_dest.id = Id::random();
save_config(
config_dest,
@@ -92,8 +91,8 @@ impl CopyCmd {
}
let repo_dest = repo_dest.open()?;
- info!("copying to target {}...", repo_dest.name);
- if poly != repo_dest.config.poly()? {
+ info!("copying to target {:?}...", repo_dest); // TODO: repo_dest.name
+ if poly != repo_dest.config().poly()? {
bail!("cannot copy to repository with different chunker parameter (re-chunking not implemented)!");
}
copy(&snapshots, &index, &repo_dest)?;
diff --git a/src/commands/diff.rs b/src/commands/diff.rs
index b1c6e42fc..0614718e5 100644
--- a/src/commands/diff.rs
+++ b/src/commands/diff.rs
@@ -16,7 +16,7 @@ use anyhow::{anyhow, bail, Context, Result};
use rustic_core::{
hash, IndexBackend, LocalDestination, LocalSource, LocalSourceFilterOptions,
- LocalSourceSaveOptions, Node, NodeStreamer, NodeType, Progress, ProgressBars, ReadIndex,
+ LocalSourceSaveOptions, Node, NodeStreamer, NodeType, Open, Progress, ProgressBars, ReadIndex,
ReadSourceEntry, RusticResult, SnapshotFile, Tree,
};
@@ -58,7 +58,7 @@ impl DiffCmd {
let repo = open_repository(get_repository(&config));
- let be = &repo.dbe;
+ let be = repo.dbe();
let (id1, path1) = arg_to_snap_path(&self.snap1, "");
let (id2, path2) = arg_to_snap_path(&self.snap2, path1);
diff --git a/src/commands/key.rs b/src/commands/key.rs
index 94607ab20..132558c06 100644
--- a/src/commands/key.rs
+++ b/src/commands/key.rs
@@ -14,7 +14,7 @@ use std::{fs::File, io::BufReader};
use dialoguer::Password;
-use rustic_core::{hash, read_password_from_reader, FileType, KeyFile, WriteBackend};
+use rustic_core::{hash, read_password_from_reader, FileType, KeyFile, Open, WriteBackend};
/// `key` subcommand
#[derive(clap::Parser, Command, Debug)]
@@ -75,8 +75,8 @@ impl AddCmd {
let repo = open_repository(get_repository(&config));
- let be = &repo.dbe;
- let key = repo.key;
+ let be = repo.dbe();
+ let key = repo.key();
let pass = self.new_password_file.as_ref().map_or_else(
|| match Password::new()
@@ -109,7 +109,7 @@ impl AddCmd {
},
);
let ko = self.key_opts.clone();
- let keyfile = KeyFile::generate(key, &pass, ko.hostname, ko.username, ko.with_created)?;
+ let keyfile = KeyFile::generate(*key, &pass, ko.hostname, ko.username, ko.with_created)?;
let data = serde_json::to_vec(&keyfile)?;
let id = hash(&data);
be.write_bytes(FileType::Key, &id, false, data.into())?;
diff --git a/src/commands/list.rs b/src/commands/list.rs
index e9b6d1ec7..eae7d5163 100644
--- a/src/commands/list.rs
+++ b/src/commands/list.rs
@@ -11,7 +11,7 @@ use abscissa_core::{Command, Runnable, Shutdown};
use anyhow::{bail, Result};
-use rustic_core::{DecryptReadBackend, FileType, IndexFile, ProgressBars, ReadBackend};
+use rustic_core::{DecryptReadBackend, FileType, IndexFile, Open, ProgressBars, ReadBackend};
/// `list` subcommand
#[derive(clap::Parser, Command, Debug)]
@@ -39,7 +39,7 @@ impl ListCmd {
let tpe = match self.tpe.as_str() {
// special treatment for listing blobs: read the index and display it
"blobs" => {
- repo.dbe
+ repo.dbe()
.stream_all::(&config.global.progress_options.progress_hidden())?
.into_iter()
.for_each(|index| {
diff --git a/src/commands/ls.rs b/src/commands/ls.rs
index 8558ce9e8..d45deee39 100644
--- a/src/commands/ls.rs
+++ b/src/commands/ls.rs
@@ -13,7 +13,7 @@ use anyhow::Result;
use std::path::Path;
use rustic_core::{
- IndexBackend, NodeStreamer, ProgressBars, SnapshotFile, Tree, TreeStreamerOptions,
+ IndexBackend, NodeStreamer, Open, ProgressBars, SnapshotFile, Tree, TreeStreamerOptions,
};
/// `ls` subcommand
@@ -47,7 +47,7 @@ impl LsCmd {
let repo = open_repository(get_repository(&config));
- let be = &repo.dbe;
+ let be = repo.dbe();
let mut recursive = self.recursive;
let (id, path) = self.snap.split_once(':').unwrap_or_else(|| {
diff --git a/src/commands/merge.rs b/src/commands/merge.rs
index 3904ea16b..e2156fb24 100644
--- a/src/commands/merge.rs
+++ b/src/commands/merge.rs
@@ -13,8 +13,8 @@ use log::info;
use chrono::Local;
use rustic_core::{
- merge_trees, BlobType, DecryptWriteBackend, FileType, Id, IndexBackend, Indexer, Node, Packer,
- PathList, Progress, ProgressBars, ReadIndex, SnapshotFile, SnapshotOptions, Tree,
+ merge_trees, BlobType, DecryptWriteBackend, FileType, Id, IndexBackend, Indexer, Node, Open,
+ Packer, PathList, Progress, ProgressBars, ReadIndex, SnapshotFile, SnapshotOptions, Tree,
};
/// `merge` subcommand
@@ -59,7 +59,7 @@ impl MergeCmd {
let repo = open_repository(get_repository(&config));
- let be = &repo.dbe;
+ let be = repo.dbe();
let p = progress_options.progress_hidden();
let snapshots = if self.ids.is_empty() {
@@ -75,7 +75,7 @@ impl MergeCmd {
be.clone(),
BlobType::Tree,
indexer.clone(),
- &repo.config,
+ repo.config(),
index.total_size(BlobType::Tree),
)?;
diff --git a/src/commands/repair.rs b/src/commands/repair.rs
index 5ebfa85e5..775109dd9 100644
--- a/src/commands/repair.rs
+++ b/src/commands/repair.rs
@@ -15,8 +15,8 @@ use anyhow::Result;
use rustic_core::{
BlobType, DecryptReadBackend, DecryptWriteBackend, FileType, Id, IndexBackend, IndexFile,
- IndexPack, IndexedBackend, Indexer, NodeType, PackHeader, PackHeaderRef, Packer, Progress,
- ProgressBars, ReadBackend, ReadIndex, SnapshotFile, StringList, Tree, WriteBackend,
+ IndexPack, IndexedBackend, Indexer, NodeType, Open, PackHeader, PackHeaderRef, Packer,
+ Progress, ProgressBars, ReadBackend, ReadIndex, SnapshotFile, StringList, Tree, WriteBackend,
};
/// `repair` subcommand
@@ -89,7 +89,7 @@ impl IndexSubCmd {
let repo = open_repository(get_repository(&config));
- let be = &repo.dbe;
+ let be = repo.dbe();
let p = progress_options.progress_spinner("listing packs...");
let mut packs: HashMap<_, _> = be.list_with_size(FileType::Pack)?.into_iter().collect();
p.finish();
@@ -237,8 +237,8 @@ impl SnapSubCmd {
let repo = open_repository(get_repository(&config));
- let be = &repo.dbe;
- let config_file = &repo.config;
+ let be = repo.dbe();
+ let config_file = repo.config();
let p = progress_options.progress_hidden();
let snapshots = if self.ids.is_empty() {
diff --git a/src/commands/restore.rs b/src/commands/restore.rs
index 568771b86..3a9c75027 100644
--- a/src/commands/restore.rs
+++ b/src/commands/restore.rs
@@ -29,7 +29,7 @@ use rayon::ThreadPoolBuilder;
use rustic_core::{
hash, DecryptReadBackend, FileType, Id, IndexBackend, IndexedBackend, LocalDestination, Node,
- NodeStreamer, NodeType, Progress, ProgressBars, RestoreStats, SnapshotFile, Tree,
+ NodeStreamer, NodeType, Open, Progress, ProgressBars, RestoreStats, SnapshotFile, Tree,
TreeStreamerOptions,
};
@@ -91,7 +91,7 @@ impl RestoreCmd {
let config = RUSTIC_APP.config();
let progress_options = &config.global.progress_options;
let repo = open_repository(get_repository(&config));
- let be = &repo.dbe;
+ let be = repo.dbe();
let (id, path) = self.snap.split_once(':').unwrap_or((&self.snap, ""));
let snap = SnapshotFile::from_str(
diff --git a/src/commands/tag.rs b/src/commands/tag.rs
index 14a26d065..1836884e1 100644
--- a/src/commands/tag.rs
+++ b/src/commands/tag.rs
@@ -12,7 +12,7 @@ use abscissa_core::{Command, Runnable, Shutdown};
use chrono::{Duration, Local};
use rustic_core::{
- DecryptWriteBackend, DeleteOption, FileType, Id, ProgressBars, SnapshotFile, StringList,
+ DecryptWriteBackend, DeleteOption, FileType, Id, Open, ProgressBars, SnapshotFile, StringList,
};
/// `tag` subcommand
@@ -81,7 +81,7 @@ impl TagCmd {
let config = RUSTIC_APP.config();
let repo = open_repository(get_repository(&config));
- let be = &repo.dbe;
+ let be = repo.dbe();
let p = config.global.progress_options.progress_hidden();
let snapshots = if self.ids.is_empty() {
diff --git a/src/config.rs b/src/config.rs
index 162c9874e..41991f522 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -131,13 +131,11 @@ fn get_config_paths(filename: &str) -> Vec {
#[cfg(target_os = "windows")]
fn get_global_config_path() -> Option {
- if let Some(program_data) = std::env::var_os("PROGRAMDATA") {
+ std::env::var_os("PROGRAMDATA").map(|program_data| {
let mut path = PathBuf::from(program_data);
path.push(r"rustic\config");
- Some(path)
- } else {
- None
- }
+ path
+ })
}
#[cfg(any(target_os = "ios", target_arch = "wasm32"))]
diff --git a/src/helpers.rs b/src/helpers.rs
index 8375cb6e1..9fb22039d 100644
--- a/src/helpers.rs
+++ b/src/helpers.rs
@@ -11,19 +11,19 @@ use log::{info, trace};
use rayon::prelude::{IntoParallelRefIterator, ParallelBridge, ParallelIterator};
use rustic_core::{
- BlobType, DecryptWriteBackend, IndexBackend, IndexedBackend, Indexer, NodeType, OpenRepository,
- Packer, Progress, ProgressBars, ReadIndex, SnapshotFile, TreeStreamerOnce,
+ BlobType, DecryptWriteBackend, IndexBackend, IndexedBackend, Indexer, NodeType, Open, Packer,
+ Progress, ProgressBars, ReadIndex, Repository, SnapshotFile, TreeStreamerOnce,
};
use crate::application::RUSTIC_APP;
-pub(crate) fn copy(
+pub(crate) fn copy
(
snapshots: &[SnapshotFile],
index: &impl IndexedBackend,
- repo_dest: &OpenRepository
,
+ repo_dest: &Repository
,
) -> Result<()> {
let config = RUSTIC_APP.config();
- let be_dest = &repo_dest.dbe;
+ let be_dest = repo_dest.dbe();
let progress_options = &config.global.progress_options;
let snapshots = relevant_snapshots(
@@ -54,14 +54,14 @@ pub(crate) fn copy
(
be_dest.clone(),
BlobType::Data,
indexer.clone(),
- &repo_dest.config,
+ repo_dest.config(),
index.total_size(BlobType::Data),
)?;
let tree_packer = Packer::new(
be_dest.clone(),
BlobType::Tree,
indexer.clone(),
- &repo_dest.config,
+ repo_dest.config(),
index.total_size(BlobType::Tree),
)?;
@@ -121,9 +121,9 @@ pub(crate) fn copy
(
Ok(())
}
-pub(crate) fn relevant_snapshots(
+pub(crate) fn relevant_snapshots(
snaps: &[SnapshotFile],
- dest_repo: &OpenRepository,
+ dest_repo: &Repository
,
filter: F,
p: &impl Progress,
) -> Result>
@@ -131,7 +131,7 @@ where
F: FnMut(&SnapshotFile) -> bool,
{
// save snapshots in destination in BTreeSet, as we want to efficiently search within to filter out already existing snapshots before copying.
- let snapshots_dest: BTreeSet<_> = SnapshotFile::all_from_backend(&dest_repo.dbe, filter, p)?
+ let snapshots_dest: BTreeSet<_> = SnapshotFile::all_from_backend(dest_repo.dbe(), filter, p)?
.into_iter()
.map(SnapshotFile::clear_ids)
.collect();