use crate::repository::commit::Commit;
use crate::repository::Result;
use super::delta::Delta;
pub struct Deltas<'a> {
inner: git2::Diff<'a>,
index: usize,
}
impl Commit<'_> {
pub fn deltas(&self) -> Result<Deltas<'_>> {
let tree = self.inner.tree()?;
let parent = if self.inner.parent_count() > 0 {
Some(self.inner.parent(0)?.tree()?)
} else {
None
};
let inner = self.repository.inner.diff_tree_to_tree(
parent.as_ref(),
Some(&tree),
Some(&mut git2::DiffOptions::new()),
)?;
Ok(Deltas { inner, index: 0 })
}
}
impl Iterator for Deltas<'_> {
type Item = Delta;
fn next(&mut self) -> Option<Self::Item> {
let delta = self.inner.get_delta(self.index)?;
self.index += 1;
let from = delta.old_file().path()?;
let path = delta.new_file().path()?;
match delta.status() {
git2::Delta::Added => {
let path = path.to_path_buf();
Some(Delta::Create { path })
}
git2::Delta::Modified => {
let path = path.to_path_buf();
Some(Delta::Modify { path })
}
git2::Delta::Copied | git2::Delta::Typechange => {
let path = path.to_path_buf();
Some(Delta::Modify { path })
}
git2::Delta::Renamed => {
let from = from.to_path_buf();
let path = path.to_path_buf();
Some(Delta::Rename { from, path })
}
git2::Delta::Deleted => {
let path = from.to_path_buf();
Some(Delta::Delete { path })
}
_ => self.next(),
}
}
}