1use std::{
2 error::Error,
3 fmt::Display,
4 path::{Path, PathBuf},
5};
6
7use files::get_existent_paths;
8use indicatif::ProgressBar;
9
10pub mod files;
11pub mod util;
12
13pub trait RecursiveOperation {
14 fn cb(&self, path: &PathBuf) -> Result<(), FileErr>;
15 fn display_cb(&mut self, path: &PathBuf, is_dir: bool);
16}
17
18#[derive(Debug)]
19pub struct FileErr {
20 source: std::io::Error,
21 pub file: String,
22}
23
24impl Display for FileErr {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 write!(f, "{}", self.source)
27 }
28}
29
30impl FileErr {
31 pub fn map<P: AsRef<Path>>(error: std::io::Error, path: P) -> FileErr {
32 FileErr {
33 source: error,
34 file: files::path_to_string(path),
35 }
36 }
37}
38
39impl Error for FileErr {
40 fn source(&self) -> Option<&(dyn Error + 'static)> {
41 Some(&self.source)
42 }
43}
44
45pub fn run_recursive_op<T: RecursiveOperation>(
48 op: &mut T,
49 paths: Vec<&Path>,
50 recurse: bool,
51) -> Result<usize, FileErr>
52where
53 T: RecursiveOperation,
54{
55 let mut counter: usize = 0;
56
57 for path in paths {
58 if path.is_dir() && recurse {
59 match files::run_op_on_dir_recursive::<T>(op, path, 0) {
60 Ok(c) => counter += c,
61 Err(e) => {
62 return Err(e);
63 }
64 };
65 } else {
66 op.display_cb(&PathBuf::from(path), false);
67 match op.cb(&PathBuf::from(path)) {
68 Ok(_) => counter += 1,
69 Err(e) => {
70 return Err(e);
71 }
72 };
73 }
74 }
75
76 Ok(counter)
77}