serde_hkx_features/verify/
dir.rs
1use super::verify_inner;
2use crate::error::{FailedReproduceFilesSnafu, Result};
3use crate::progress::ProgressHandler;
4use rayon::prelude::*;
5use std::path::{Path, PathBuf};
6
7pub fn verify_dir<D, P>(dir: D, progress: P) -> Result<()>
12where
13 D: AsRef<Path>,
14 P: ProgressHandler + Send + Sync,
15{
16 let dir = dir.as_ref();
17 verify_dir_(dir, progress)
18}
19
20fn filter_hkx_files(dir: &Path) -> Vec<PathBuf> {
21 jwalk::WalkDir::new(dir)
22 .into_iter()
23 .filter_map(|entry| entry.ok())
24 .filter(|entry| {
25 entry
26 .path()
27 .extension()
28 .is_some_and(|ext| ext.eq_ignore_ascii_case("hkx"))
29 })
30 .map(|entry| entry.path())
31 .collect()
32}
33
34fn verify_dir_<P>(dir: &Path, mut progress: P) -> Result<()>
35where
36 P: ProgressHandler + Sync + Send,
37{
38 let filtered_entries = filter_hkx_files(dir);
39 let total_files = filtered_entries.len();
40
41 if total_files == 0 {
42 progress.on_empty();
43 return Ok(());
44 }
45
46 progress.on_set_total(total_files);
47
48 let results: Vec<_> = filtered_entries
49 .into_par_iter()
50 .map(|path| {
51 let result = verify_inner(&path);
52
53 let is_valid = if let Ok((expected_bytes, actual_bytes)) = &result {
54 expected_bytes == actual_bytes
55 } else {
56 false
57 };
58
59 if is_valid {
60 progress.success_inc(1);
61 #[cfg(feature = "tracing")]
62 tracing::info!("Passed Reproduction: {}", path.display());
63 } else {
64 progress.failure_inc(1);
65 }
66
67 progress.inc(1);
68 progress.on_processing_path(path.as_path());
69
70 (path, is_valid)
71 })
72 .collect();
73
74 progress.on_finish();
75
76 let err_paths: Vec<PathBuf> = results
77 .into_par_iter()
78 .filter_map(|(path, is_valid)| if !is_valid { Some(path) } else { None })
79 .collect();
80
81 if err_paths.is_empty() {
82 Ok(())
83 } else {
84 FailedReproduceFilesSnafu {
85 path: dir.to_path_buf(),
86 total_files,
87 err_paths,
88 }
89 .fail()
90 }
91}