use std::path::Path;
use bytes::Bytes;
use crate::{
backend::{FileType, FindInBackend, decrypt::DecryptReadBackend},
blob::{BlobId, BlobType, tree::Tree},
error::{ErrorKind, RusticError, RusticResult},
index::ReadIndex,
repofile::SnapshotFile,
repository::{IndexedFull, IndexedTree, Open, Repository},
};
pub(crate) fn cat_file<S: Open>(
repo: &Repository<S>,
tpe: FileType,
id: &str,
) -> RusticResult<Bytes> {
let id = repo.dbe().find_id(tpe, id)?;
let data = repo.dbe().read_encrypted_full(tpe, &id)?;
Ok(data)
}
pub(crate) fn cat_blob<S: IndexedFull>(
repo: &Repository<S>,
tpe: BlobType,
id: &str,
) -> RusticResult<Bytes> {
let id = id.parse()?;
let data = repo.index().blob_from_backend(repo.dbe(), tpe, &id)?;
Ok(data)
}
pub(crate) fn cat_tree<S: IndexedTree>(
repo: &Repository<S>,
snap: &str,
sn_filter: impl FnMut(&SnapshotFile) -> bool + Send + Sync,
) -> RusticResult<Bytes> {
let (id, path) = snap.split_once(':').unwrap_or((snap, ""));
let snap = SnapshotFile::from_str(
repo.dbe(),
id,
sn_filter,
&repo.progress_counter("getting snapshot..."),
)?;
let node = Tree::node_from_path(repo.dbe(), repo.index(), snap.tree, Path::new(path))?;
let id = node.subtree.ok_or_else(|| {
RusticError::new(
ErrorKind::InvalidInput,
"Path `{path}` in Node subtree is not a directory. Please provide a directory path.",
)
.attach_context("path", path.to_string())
})?;
let data = repo
.index()
.blob_from_backend(repo.dbe(), BlobType::Tree, &BlobId::from(*id))?;
Ok(data)
}