71 lines
2.6 KiB
Rust
71 lines
2.6 KiB
Rust
use diff::Result;
|
|
use hex;
|
|
use log::{debug, trace};
|
|
use sha3::{Digest, Sha3_256};
|
|
use std::fs;
|
|
use std::io::{self, Error};
|
|
use std::path::Path;
|
|
|
|
pub(crate) fn filesum_filtered(
|
|
path: &Path,
|
|
oldfile: &mut String,
|
|
diff_string: &mut String,
|
|
re: Option<®ex::Regex>,
|
|
) -> io::Result<(bool, String)> {
|
|
// Open file for hashing
|
|
match re {
|
|
Some(v) => debug!("try to open file {:?} for hashing using filter regex {}", path, v),
|
|
None => debug!("try to open file {:?} for hashing", path),
|
|
}
|
|
let mut hasher = Sha3_256::new();
|
|
let mut filedata = String::with_capacity(2048);
|
|
let mut changed = false;
|
|
|
|
// we read only smal files, so its fast to read the whole file to memory, so we can also du a diff
|
|
if let Ok(file_contents) = fs::read_to_string(path) {
|
|
if let Some(re) = re {
|
|
debug!("Filter lines with regex {:?}", re);
|
|
for line in file_contents.lines() {
|
|
if re.is_match(line) {
|
|
trace!("line {} skipped by filter regex", line);
|
|
continue;
|
|
}
|
|
// Update the hasher with the bytes
|
|
filedata.push_str(line);
|
|
}
|
|
} else {
|
|
// we do not have a filter regex, so we could simply paste the file to the hasher
|
|
debug!("Hash file without filter regex");
|
|
filedata = file_contents;
|
|
}
|
|
hasher.update(format!("{}\n", filedata).as_bytes());
|
|
if !oldfile.is_empty() && *oldfile != filedata {
|
|
diff_string.clear();
|
|
for diff in diff::lines(oldfile, &filedata) {
|
|
match diff {
|
|
Result::Left(l) => {
|
|
trace!("Diff - {}", l); // Removed line
|
|
diff_string.push_str(&format!("-{}\n", l));
|
|
}
|
|
Result::Both(l, _) => {
|
|
trace!("Diff {}", l); // Unchanged line
|
|
}
|
|
Result::Right(r) => {
|
|
trace!("Diff + {}", r); // Added line
|
|
diff_string.push_str(&format!("+{}\n", r));
|
|
}
|
|
}
|
|
}
|
|
debug!("Diff for {:?} is now {}", path, diff_string);
|
|
changed = true;
|
|
*oldfile = filedata;
|
|
} else if oldfile.is_empty() {
|
|
*oldfile = filedata;
|
|
}
|
|
// Finalize the hash and convert it to a hexadecimal string
|
|
let hash = hex::encode(hasher.finalize());
|
|
return Ok((changed, hash));
|
|
}
|
|
Err(Error::other(format!("Unable to read file {:?}", path)))
|
|
}
|