blob: 1c0dc7539b6525e69c26eabb1c91f55edcfe48da [file] [log] [blame]
use std::sync::atomic::AtomicBool;
use crate::File;
mod error {
/// The error returned by [File::verify_integrity()][super::File::verify_integrity()].
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum Error {
#[error("Could not read index file to generate hash")]
Io(#[from] std::io::Error),
#[error("Index checksum should have been {expected}, but was {actual}")]
ChecksumMismatch {
actual: gix_hash::ObjectId,
expected: gix_hash::ObjectId,
},
}
}
pub use error::Error;
impl File {
/// Verify the integrity of the index to assure its consistency.
pub fn verify_integrity(&self) -> Result<(), Error> {
let _span = gix_features::trace::coarse!("gix_index::File::verify_integrity()");
if let Some(checksum) = self.checksum {
let num_bytes_to_hash = self.path.metadata()?.len() - checksum.as_bytes().len() as u64;
let should_interrupt = AtomicBool::new(false);
let actual = gix_features::hash::bytes_of_file(
&self.path,
num_bytes_to_hash,
checksum.kind(),
&mut gix_features::progress::Discard,
&should_interrupt,
)?;
(actual == checksum).then_some(()).ok_or(Error::ChecksumMismatch {
actual,
expected: checksum,
})
} else {
Ok(())
}
}
}