use std::fs::File;
use std::path::Path;
use crate::bundle::{
write_bundle, Bundle, BundleError, BundleSpec, BundleVerifyReport, UnbundleOutcome,
UnbundledRef,
};
use crate::list_limit::Limited;
use crate::objects::ObjectId;
use crate::progress::{NullProgress, ProgressSink};
use crate::repo::Repository;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BundleHead {
pub name: String,
pub oid: ObjectId,
}
#[derive(Debug, Copy, Clone)]
pub struct RepositoryBundles<'repo> {
repo: &'repo Repository,
}
impl<'repo> RepositoryBundles<'repo> {
pub(crate) fn new(repo: &'repo Repository) -> Self {
Self { repo }
}
#[must_use]
pub fn repository(&self) -> &'repo Repository {
self.repo
}
pub fn create(&self, spec: &BundleSpec, path: &Path) -> std::result::Result<(), BundleError> {
let file = File::create(path).map_err(|e| BundleError::Io(e.to_string()))?;
let mut out = std::io::BufWriter::new(file);
write_bundle(self.repo, spec, &mut out)
}
pub fn verify(&self, path: &Path) -> std::result::Result<BundleVerifyReport, BundleError> {
Bundle::open(path)?.verify(self.repo)
}
pub fn list_heads(
&self,
path: &Path,
limit: Option<usize>,
) -> std::result::Result<Limited<BundleHead>, BundleError> {
let bundle = Bundle::open(path)?;
let heads: Vec<BundleHead> = bundle
.header()
.refs
.iter()
.map(|(name, oid)| BundleHead {
name: name.clone(),
oid: *oid,
})
.collect();
Ok(Limited::from_vec(heads, limit))
}
pub fn unbundle(&self, path: &Path) -> std::result::Result<UnbundleOutcome, BundleError> {
Bundle::open(path)?.unbundle_with_progress(self.repo, &mut NullProgress)
}
pub fn unbundle_with_progress(
&self,
path: &Path,
progress: &mut dyn ProgressSink,
) -> std::result::Result<UnbundleOutcome, BundleError> {
Bundle::open(path)?.unbundle_with_progress(self.repo, progress)
}
pub fn open(&self, path: impl AsRef<Path>) -> std::result::Result<Bundle, BundleError> {
Bundle::open(path)
}
}
impl From<UnbundledRef> for BundleHead {
fn from(value: UnbundledRef) -> Self {
Self {
name: value.name,
oid: value.oid,
}
}
}