file_hashing/folder.rs
1//! Folder functions
2
3use super::*;
4use std::path::PathBuf;
5
6/// Get hash from **folder**
7///
8/// This function gets all files from a folder recursively and gets their hash
9///
10/// # Example
11///
12/// ```no_run
13/// use std::path::PathBuf;
14/// use blake2::{Blake2s256, Digest};
15/// use file_hashing::get_hash_folder;
16///
17/// let mut hash = Blake2s256::new();
18///
19/// let result = get_hash_folder(
20/// &PathBuf::from("/home/gladi/Pictures"),
21/// &mut hash,
22/// 12,
23/// |_| {},
24/// )
25/// .unwrap();
26///
27/// assert_eq!(result.len(), 64); // Blake2s256 len == 64
28/// ```
29///
30/// # Error
31///
32/// * If the folder **is empty**, the **IOErrorKind::InvalidInput** error will be returned
33pub fn get_hash_folder<HashType, P>(
34 dir: P,
35 hash: &mut HashType,
36 num_threads: usize,
37 progress: impl Fn(ProgressInfo),
38) -> Result<String, IOError>
39where
40 HashType: DynDigest + Clone + std::marker::Send,
41 P: AsRef<Path> + std::marker::Sync,
42{
43 get_hash_files(
44 &fs::get_all_file_from_folder(dir),
45 hash,
46 num_threads,
47 progress,
48 )
49}
50
51/// Get hash from **folders**
52///
53/// This function gets all files from a folders recursively and gets their hash
54///
55/// # Example
56///
57/// ```no_run
58/// use std::path::PathBuf;
59/// use blake2::{Blake2s256, Digest};
60/// use file_hashing::get_hash_folders;
61///
62/// let mut hash = Blake2s256::new();
63///
64/// let result = get_hash_folders(
65/// &vec![PathBuf::from("/home/gladi/Pictures"), PathBuf::from("/home/gladi/Hentai")],
66/// &mut hash,
67/// 12,
68/// |_| {},
69/// )
70/// .unwrap();
71///
72/// assert_eq!(result.len(), 64); // Blake2s256 len == 64
73/// ```
74///
75/// # Error
76///
77/// * If the folders **is empty**, the **IOErrorKind::InvalidInput** error will be returned
78pub fn get_hash_folders<HashType, P>(
79 dirs: &Vec<P>,
80 hash: &mut HashType,
81 num_threads: usize,
82 progress: impl Fn(ProgressInfo),
83) -> Result<String, IOError>
84where
85 HashType: DynDigest + Clone + std::marker::Send,
86 P: AsRef<Path> + std::marker::Sync,
87{
88 let mut paths: Vec<PathBuf> = vec![];
89
90 for dir in dirs {
91 paths.append(&mut fs::get_all_file_from_folder(dir));
92 }
93
94 get_hash_files(&paths, hash, num_threads, progress)
95}
96
97#[cfg(test)]
98mod tests {
99 use crate::fs::extra;
100 use blake2::{Blake2s256, Digest};
101
102 #[test]
103 fn get_hash_folder() {
104 let mut hash = Blake2s256::new();
105 let (temp_dir, _path) =
106 extra::generate_random_folder_with_files(325, 32);
107
108 let result = super::get_hash_folder(
109 &temp_dir.to_path_buf(),
110 &mut hash,
111 12,
112 |_| {},
113 )
114 .unwrap();
115
116 println!("result: {}", result);
117 assert_eq!(result.len(), 64); // Blake2s256 len == 64
118 }
119
120 #[test]
121 fn get_hash_folders() {
122 let mut hash = Blake2s256::new();
123 let (temp_dir1, _path1) =
124 extra::generate_random_folder_with_files(325, 32);
125 let (temp_dir2, _path2) =
126 extra::generate_random_folder_with_files(325, 32);
127
128 let result = super::get_hash_folders(
129 &vec![temp_dir1.to_path_buf(), temp_dir2.to_path_buf()],
130 &mut hash,
131 12,
132 |_| {},
133 )
134 .unwrap();
135
136 println!("result: {}", result);
137 assert_eq!(result.len(), 64); // Blake2s256 len == 64
138 }
139}