gix_index/file/
verify.rs

1use std::sync::atomic::AtomicBool;
2
3use crate::File;
4
5mod error {
6    /// The error returned by [File::verify_integrity()][super::File::verify_integrity()].
7    #[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    /// Verify the integrity of the index to assure its consistency.
23    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}