rrc_lib/
lib.rs

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
45///This function runs the callbacks of a RecursiveOperation on a given set of paths.
46/// Please note that it does not check if the path exists.
47pub 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}