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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use std::fs::{File, OpenOptions};
use std::io::{Read, Write};
use std::path::Path;
use crate::utils::{log, LogLevel};
use std::collections::HashMap;
use md5;
fn hash_u8(v: &[u8]) -> String {
let digest = md5::compute(v);
return format!("{:x}", digest);
}
fn hash_file(path: &str) -> String {
let mut file = File::open(path).unwrap();
let mut contents = Vec::new();
file.read_to_end(&mut contents).unwrap();
return hash_u8(&contents);
}
pub fn get_hash(path: &str, path_hash: &HashMap<String, String>) -> Option<String> {
if path_hash.contains_key(path) {
return Some(path_hash.get(path).unwrap().to_string());
}
return None;
}
pub fn load_hashes_from_file(path: &str) -> HashMap<String, String> {
let mut path_hash: HashMap<String, String> = HashMap::new();
let path = Path::new(path);
if !path.exists() {
return path_hash;
}
let mut file = OpenOptions::new().read(true).open(path).unwrap();
let mut contents = String::new();
file.read_to_string(&mut contents).unwrap();
for line in contents.lines() {
if line.is_empty() {
continue;
}
let mut split = line.split(" ");
let path = split.next().unwrap();
let hash = split.next().unwrap();
path_hash.insert(path.to_string(), hash.to_string());
}
return path_hash;
}
pub fn save_hashes_to_file(path: &str, path_hash: &HashMap<String, String>) {
let mut file = OpenOptions::new().write(true).create(true).open(path).unwrap();
for (path, hash) in path_hash {
let line = format!("{} {}\n", path, hash);
file.write(line.as_bytes()).unwrap();
}
log(LogLevel::Debug, &format!("Saved hashes to file: {:?}", path_hash));
}
pub fn is_file_changed(path: &str, path_hash: &HashMap<String, String>) -> bool {
let hash = get_hash(path, path_hash);
if hash.is_none() {
return true;
}
let hash = hash.unwrap();
let new_hash = hash_file(path);
let result = hash != new_hash;
if result {
log(LogLevel::Debug, &format!("File changed, updating hash for file: {}", path));
log(LogLevel::Debug, &format!("\tOld hash: {}", hash));
log(LogLevel::Debug, &format!("\tNew hash: {}", new_hash));
}
result
}
pub fn save_hash(path: &str, path_hash: &mut HashMap<String, String>) {
let new_hash = hash_file(path);
let hash = get_hash(path, path_hash);
if hash.is_none() {
path_hash.insert(path.to_string(), new_hash);
return;
}
let hash = hash.unwrap();
if hash != new_hash {
log(LogLevel::Info, &format!("File changed, updating hash for file: {}", path));
path_hash.insert(path.to_string(), new_hash);
return;
}
}