use git_zero_core::{Error, ObjectFormat, ObjectId, ObjectKind, Result};
pub struct Ancestry {
format: ObjectFormat,
target: Option<ObjectId>,
remaining: u64,
}
impl Ancestry {
pub const fn new(format: ObjectFormat, max_visits: u64) -> Self {
Self {
format,
target: None,
remaining: max_visits,
}
}
pub fn start(&mut self, old: ObjectId) -> Result<()> {
self.target = None;
if self.remaining == 0 {
return Err(Error::LimitExceeded);
}
if old.format() != self.format || old.is_zero() {
return Err(Error::InvalidObjectId);
}
self.target = Some(old);
Ok(())
}
pub fn visit(&mut self, id: ObjectId, kind: ObjectKind) -> Result<bool> {
let target = self.target.ok_or(Error::InvalidRequest)?;
if self.remaining == 0 {
return Err(Error::LimitExceeded);
}
if id.format() != self.format || id.is_zero() {
return Err(Error::InvalidObjectId);
}
if kind != ObjectKind::Commit {
return Err(Error::InvalidObject);
}
self.remaining -= 1;
let found = target == id;
if found {
self.target = None;
}
Ok(found)
}
}