use std::{
collections::{HashMap, HashSet},
fs,
path::PathBuf,
};
use walkdir::WalkDir;
fn join(
first_file_list: HashMap<PathBuf, PathBuf>,
second_file_list: HashMap<PathBuf, PathBuf>,
) -> Vec<(PathBuf, PathBuf)> {
let all_suffixes: HashSet<_> = first_file_list
.keys()
.chain(second_file_list.keys())
.collect();
let mut pairs: Vec<(PathBuf, PathBuf)> = Vec::new();
for suffix in all_suffixes {
let first_path = first_file_list
.get(suffix)
.expect(format!("No file {suffix:?} in first folder").as_str());
let second_path = second_file_list
.get(suffix)
.expect(format!("No file {suffix:?} in second folder").as_str());
pairs.push((first_path.to_owned(), second_path.to_owned()));
}
pairs
}
fn browse_folder(path: &str) -> HashMap<PathBuf, PathBuf> {
WalkDir::new(path)
.into_iter()
.filter_map(Result::ok)
.filter(|f| f.file_type().is_file())
.map(|f| {
(
f.path().strip_prefix(path).unwrap().to_path_buf(),
f.path().to_path_buf(),
)
})
.collect()
}
fn compare_files_content(first_file_path: PathBuf, second_file_path: PathBuf) {
let first_file = fs::read_to_string(first_file_path.to_owned())
.expect(format!("impossible to read {:?}", first_file_path).as_str());
let second_file = fs::read_to_string(second_file_path.to_owned())
.expect(format!("impossible to read {:?}", second_file_path).as_str());
for (idx, content) in first_file.lines().zip(second_file.lines()).enumerate() {
if content.0.ne(content.1) {
panic!(
"{:?} and {:?} are different at line {}",
first_file_path,
second_file_path,
idx + 1
);
}
}
}
pub fn compare_folders_content(first_path: &str, second_path: &str) {
let first_file_list = browse_folder(&first_path);
let second_file_list = browse_folder(&second_path);
let pairs = join(first_file_list, second_file_list);
for pair in pairs {
compare_files_content(pair.0, pair.1);
}
}