summaryrefslogtreecommitdiffstats
path: root/src/directories.rs
blob: ad3f3dc68c34fa7120ace96017d20deddfcd8908 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
use ignore::WalkBuilder;
use std::{ops::Deref, path::PathBuf};

pub use config::Config;
pub use error::{Error, Result};

mod config;
mod error;

#[derive(Debug, PartialEq, Eq, Default)]
pub struct Directories {
    directories: Vec<PathBuf>,
    config: Config,
}

impl Directories {
    pub(crate) fn new(config: &Config) -> Directories {
        Directories {
            directories: config.add.to_owned(),
            config: config.to_owned(),
        }
    }

    pub(crate) fn walk(&mut self) -> Result<&mut Directories> {
        let mut dirs = self.config.search.iter().cloned();

        // Taking first element is neccissary due to requirement of an initial item
        // in the WalkBuilder API
        //
        // See: https://github.com/BurntSushi/ripgrep/issues/1761
        let first = dirs.next().unwrap_or_default();
        let mut walk = WalkBuilder::new(first);
        let walk = walk.standard_filters(true).max_depth(Some(1));

        let results = dirs
            .fold(walk, |walk, dir| walk.add(dir))
            .build()
            .map(|r| r.map(|d| d.into_path()))
            .collect::<std::result::Result<Vec<_>, _>>();

        self.directories.extend(results?);
        Ok(self)
    }

    pub fn as_stdin(&self) -> String {
        self.directories
            .iter()
            .cloned()
            .map(|p: PathBuf| p.to_string_lossy().into())
            .collect::<Vec<String>>()
            .join("\n")
    }
}

impl Deref for Directories {
    type Target = Vec<PathBuf>;

    fn deref(&self) -> &Self::Target {
        &self.directories
    }
}