use std::path::Path;
use anyhow::Result;
use crate::git;
pub(crate) struct DiffTracker<'a> {
path: &'a Path,
baseline: DiffBaseline,
}
enum DiffBaseline {
Unknown,
Snapshot(Vec<u8>),
}
impl<'a> DiffTracker<'a> {
pub(crate) fn clean_baseline(path: &'a Path) -> Self {
Self {
path,
baseline: DiffBaseline::Snapshot(Vec::new()),
}
}
pub(crate) fn unknown_baseline(path: &'a Path) -> Self {
Self {
path,
baseline: DiffBaseline::Unknown,
}
}
pub(crate) async fn prepare_for_group(&mut self, track_changes: bool) -> Result<()> {
if track_changes && let DiffBaseline::Unknown = self.baseline {
self.baseline = DiffBaseline::Snapshot(git::diff_worktree(self.path).await?);
}
Ok(())
}
pub(crate) async fn changed_after_group(&mut self, track_changes: bool) -> Result<bool> {
if !track_changes {
return Ok(false);
}
match &mut self.baseline {
DiffBaseline::Snapshot(prev_diff) => {
let curr_diff = git::diff_worktree(self.path).await?;
let modified = curr_diff != *prev_diff;
*prev_diff = curr_diff;
Ok(modified)
}
DiffBaseline::Unknown => {
unreachable!("diff baseline must be captured before hooks can modify files")
}
}
}
pub(crate) fn invalidate(&mut self) {
self.baseline = DiffBaseline::Unknown;
}
}