1use std::sync::atomic::AtomicBool;
2
3use crate::File;
4
5mod error {
6 #[derive(Debug, thiserror::Error)]
8 #[allow(missing_docs)]
9 pub enum Error {
10 #[error("Could not read index file to generate hash")]
11 Io(#[from] std::io::Error),
12 #[error("Index checksum should have been {expected}, but was {actual}")]
13 ChecksumMismatch {
14 actual: gix_hash::ObjectId,
15 expected: gix_hash::ObjectId,
16 },
17 }
18}
19pub use error::Error;
20
21impl File {
22 pub fn verify_integrity(&self) -> Result<(), Error> {
24 let _span = gix_features::trace::coarse!("gix_index::File::verify_integrity()");
25 if let Some(checksum) = self.checksum {
26 let num_bytes_to_hash = self.path.metadata()?.len() - checksum.as_bytes().len() as u64;
27 let should_interrupt = AtomicBool::new(false);
28 let actual = gix_features::hash::bytes_of_file(
29 &self.path,
30 num_bytes_to_hash,
31 checksum.kind(),
32 &mut gix_features::progress::Discard,
33 &should_interrupt,
34 )?;
35 (actual == checksum).then_some(()).ok_or(Error::ChecksumMismatch {
36 actual,
37 expected: checksum,
38 })
39 } else {
40 Ok(())
41 }
42 }
43}