(self, control: &ControlToken<Self::Status>)
| 170 | type Status = (PathBuf, FolderSummary); |
| 171 | |
| 172 | fn run(self, control: &ControlToken<Self::Status>) -> Self::Output { |
| 173 | let FolderScan { path, excludes } = self; |
| 174 | let mut ds = FolderInfo::new(&path); |
| 175 | let incompressible = pathdb(); |
| 176 | let mut incompressible = incompressible.write().unwrap(); |
| 177 | let _ = incompressible.load(); |
| 178 | |
| 179 | let mut last_status = Instant::now(); |
| 180 | |
| 181 | // 1. Handle excludes separately for directories to allow pruning, while |
| 182 | // still recording accurate sizes for files. |
| 183 | // 2. Ignore errors - consider recording them somewhere in future. |
| 184 | // 3. Only process files. |
| 185 | // 4. Grab metadata - should be infallible on Windows, it comes with the |
| 186 | // DirEntry. |
| 187 | // 5. GetCompressedFileSizeW() or skip. |
| 188 | let walker = WalkDir::new(&path) |
| 189 | .into_iter() |
| 190 | .filter_entry(|e| e.file_type().is_file() || !excludes.is_match(e.path())) |
| 191 | .filter_map(|e| e.map_err(|e| eprintln!("Error: {:?}", e)).ok()) |
| 192 | .filter(|e| e.file_type().is_file()) |
| 193 | .filter_map(|e| e.metadata().map(|md| (e, md)).ok()) |
| 194 | .filter_map(|(e, md)| e.path().size_on_disk().map(|s| (e, md, s)).ok()) |
| 195 | .enumerate(); |
| 196 | |
| 197 | for (count, (entry, metadata, physical)) in walker { |
| 198 | let shortname = entry |
| 199 | .path() |
| 200 | .strip_prefix(&path) |
| 201 | .unwrap_or_else(|_e| entry.path()) |
| 202 | .to_path_buf(); |
| 203 | |
| 204 | let fi = FileInfo { |
| 205 | path: shortname, |
| 206 | logical_size: metadata.len().max(physical), |
| 207 | physical_size: physical, |
| 208 | }; |
| 209 | |
| 210 | if count % 8 == 0 { |
| 211 | if control.is_cancelled_with_pause() { |
| 212 | return Err(ds); |
| 213 | } |
| 214 | |
| 215 | if last_status.elapsed() >= Duration::from_millis(50) { |
| 216 | last_status = Instant::now(); |
| 217 | control.set_status((fi.path.clone(), ds.summary())); |
| 218 | } |
| 219 | } |
| 220 | |
| 221 | if fi.physical_size < fi.logical_size { |
| 222 | ds.push(FileKind::Compressed, fi); |
| 223 | } else if fi.logical_size <= 4096 |
| 224 | || metadata.file_attributes() |
| 225 | & (FILE_ATTRIBUTE_READONLY |
| 226 | | FILE_ATTRIBUTE_SYSTEM |
| 227 | | FILE_ATTRIBUTE_TEMPORARY |
| 228 | | FILE_ATTRIBUTE_COMPRESSED) |
| 229 | != 0 |
nothing calls this directly
no test coverage detected