summaryrefslogtreecommitdiffstats
path: root/vendor/gix-index/src/file/verify.rs
blob: 6743b37a7c1a5f7eb7b44c87a5cf528702f9c04b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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,
        },
        #[error("Checksum of in-memory index wasn't computed yet")]
        NoChecksum,
    }
}
pub use error::Error;

impl File {
    /// Verify the integrity of the index to assure its consistency.
    pub fn verify_integrity(&self) -> Result<(), Error> {
        let checksum = self.checksum.ok_or(Error::NoChecksum)?;
        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 as usize,
            checksum.kind(),
            &mut gix_features::progress::Discard,
            &should_interrupt,
        )?;
        (actual == checksum).then_some(()).ok_or(Error::ChecksumMismatch {
            actual,
            expected: checksum,
        })
    }
}