use crate::blockdir::BlockDir;
use crate::stitch::IterStitchedIndexHunks;
use crate::stored_file::{ReadStoredFile, StoredFile};
use crate::*;
pub struct StoredTree {
band: Band,
archive: Archive,
block_dir: BlockDir,
}
impl StoredTree {
pub(crate) fn open(archive: &Archive, band_id: &BandId) -> Result<StoredTree> {
Ok(StoredTree {
band: Band::open(archive, band_id)?,
block_dir: archive.block_dir().clone(),
archive: archive.clone(),
})
}
pub fn band(&self) -> &Band {
&self.band
}
pub fn is_closed(&self) -> Result<bool> {
self.band.is_closed()
}
fn open_stored_file(&self, entry: &IndexEntry) -> StoredFile {
StoredFile::open(self.block_dir.clone(), entry.addrs.clone())
}
}
impl ReadTree for StoredTree {
type R = ReadStoredFile;
type Entry = IndexEntry;
type IT = index::IndexEntryIter<stitch::IterStitchedIndexHunks>;
fn iter_entries(&self, subtree: Apath, exclude: Exclude) -> Result<Self::IT> {
Ok(
IterStitchedIndexHunks::new(&self.archive, Some(self.band.id().clone()))
.iter_entries(subtree, exclude),
)
}
fn file_contents(&self, entry: &Self::Entry) -> Result<Self::R> {
Ok(self.open_stored_file(entry).into_read())
}
fn estimate_count(&self) -> Result<u64> {
self.band.index().estimate_entry_count()
}
}
#[cfg(test)]
mod test {
use std::path::Path;
use super::super::test_fixtures::*;
use super::super::*;
#[test]
pub fn open_stored_tree() {
let af = ScratchArchive::new();
af.store_two_versions();
let last_band_id = af.last_band_id().unwrap().unwrap();
let st = af.open_stored_tree(BandSelectionPolicy::Latest).unwrap();
assert_eq!(*st.band().id(), last_band_id);
let names: Vec<String> = st
.iter_entries(Apath::root(), Exclude::nothing())
.unwrap()
.map(|e| e.apath.into())
.collect();
let expected = if SYMLINKS_SUPPORTED {
vec![
"/",
"/hello",
"/hello2",
"/link",
"/subdir",
"/subdir/subfile",
]
} else {
vec!["/", "/hello", "/hello2", "/subdir", "/subdir/subfile"]
};
assert_eq!(expected, names);
}
#[test]
pub fn cant_open_no_versions() {
let af = ScratchArchive::new();
match af.open_stored_tree(BandSelectionPolicy::Latest) {
Err(Error::ArchiveEmpty) => (),
Err(other) => panic!("unexpected result {other:?}"),
Ok(_) => panic!("unexpected success"),
}
}
#[test]
fn iter_entries() {
let archive = Archive::open_path(Path::new("testdata/archive/minimal/v0.6.3/")).unwrap();
let st = archive
.open_stored_tree(BandSelectionPolicy::Latest)
.unwrap();
let names: Vec<String> = st
.iter_entries("/subdir".into(), Exclude::nothing())
.unwrap()
.map(|entry| entry.apath.into())
.collect();
assert_eq!(names.as_slice(), ["/subdir", "/subdir/subfile"]);
}
}