use std::fs::File;
use std::io::{Read, BufReader, BufRead};
use md5::{Md5, Digest};
use crate::data::{FileInfo, FileList};
use my_logger::{log, logw, logd};
use chrono::Local;
pub fn hash_file_list() -> FileList {
logw!("STATUS: Hashing files: Please wait...");
let date = Local::now().format("%Y-%m-%d").to_string();
let mut liste = FileList {
date,
files: vec![],
};
let actual_filename = "file_list.txt";
let file = match File::open(actual_filename) {
Ok(file) => file,
Err(error) => {
logd!("ERROR: Can't open file '{}': {}", actual_filename, error);
return liste;
}
};
let reader = BufReader::new(file);
for line_result in reader.lines() {
let line = match line_result {
Ok(line) => line,
Err(error) => {
log!("ERROR: Can't read line from file '{}': {}", actual_filename, error);
continue;
}
};
if !line.starts_with("/sys/") && !line.starts_with("/dev/")
&& !line.starts_with("/run/") && !line.starts_with("/proc/") {
let file_info = hash_file(line);
liste.files.push(file_info);
}
}
log!("STATUS: Hashing files: Success !");
liste
}
pub fn hash_file(filename: String) -> FileInfo {
let mut file = match File::open(filename.clone()) {
Ok(file) => file,
Err(_) => {
logw!("ERROR: Can't open file: {}", filename);
return FileInfo {
filename,
md5_hash: String::from("none"),
};
}
};
let mut buffer = Vec::new();
if let Err(error) = file.read_to_end(&mut buffer) {
log!("ERROR: Can't read file: {}", error);
return FileInfo {
filename,
md5_hash: String::from("none"),
};
}
let input = match String::from_utf8(buffer) {
Ok(input) => input,
Err(_) => {
return FileInfo {
filename,
md5_hash: String::from("none"),
};
}
};
FileInfo {
filename,
md5_hash: calculate_md5_hash(&input),
}
}
pub fn calculate_md5_hash(input: &String) -> String {
let mut hasher = Md5::new();
hasher.update(input);
let result = hasher.finalize();
let hash_string = format!("{:x}", result);
hash_string
}
#[doc(hidden)]
#[cfg(test)]
mod tests {
use std::{fs::File, io::Write};
use tempfile::tempdir;
use crate::{hash_file, FileInfo};
use super::calculate_md5_hash;
#[test]
fn test_calculate_md5_hash() {
let input = String::from("hello, world");
let expected_hash = "e4d7f1b4ed2e42d15898f4b27b019da4";
let calculated_hash = calculate_md5_hash(&input);
assert_eq!(calculated_hash, expected_hash);
}
#[test]
fn test_hash_file_valid_file() {
let temp_dir = tempdir().expect("Failed to create temporary directory");
let temp_file_path = temp_dir.path().join("test_file.txt");
let mut temp_file = File::create(&temp_file_path).expect("Failed to create temporary file");
temp_file
.write_all(b"This is a test file.\n") .expect("Failed to write to temporary file");
let expected_hash = "2d282102fa671256327d4767ec23bc6b";
let result = hash_file(temp_file_path.display().to_string());
assert_eq!(result.md5_hash, expected_hash);
}
#[test]
fn test_hash_file_nonexistent_file() {
let file_path = "nonexistent_file.txt";
let result = hash_file(file_path.to_string());
let expected_result = FileInfo {
filename: file_path.to_string(),
md5_hash: "none".to_string(),
};
assert_eq!(result.md5_hash, expected_result.md5_hash);
}
#[test]
fn test_hash_file_list_with_test_files() {
}
#[test]
fn test_hash_file_list_exclude_files() {
}
}