ignore.rs

 1use ignore::gitignore::Gitignore;
 2use std::{ffi::OsStr, path::Path, sync::Arc};
 3
 4#[derive(Debug)]
 5pub enum IgnoreStack {
 6    None,
 7    Some {
 8        abs_base_path: Arc<Path>,
 9        ignore: Arc<Gitignore>,
10        parent: Arc<IgnoreStack>,
11    },
12    All,
13}
14
15impl IgnoreStack {
16    pub fn none() -> Arc<Self> {
17        Arc::new(Self::None)
18    }
19
20    pub fn all() -> Arc<Self> {
21        Arc::new(Self::All)
22    }
23
24    pub fn append(self: Arc<Self>, abs_base_path: Arc<Path>, ignore: Arc<Gitignore>) -> Arc<Self> {
25        match self.as_ref() {
26            IgnoreStack::All => self,
27            _ => Arc::new(Self::Some {
28                abs_base_path,
29                ignore,
30                parent: self,
31            }),
32        }
33    }
34
35    pub fn is_abs_path_ignored(&self, abs_path: &Path, is_dir: bool) -> bool {
36        if is_dir && abs_path.file_name() == Some(OsStr::new(".git")) {
37            return true;
38        }
39
40        match self {
41            Self::None => false,
42            Self::All => true,
43            Self::Some {
44                abs_base_path,
45                ignore,
46                parent: prev,
47            } => match ignore.matched(abs_path.strip_prefix(abs_base_path).unwrap(), is_dir) {
48                ignore::Match::None => prev.is_abs_path_ignored(abs_path, is_dir),
49                ignore::Match::Ignore(_) => true,
50                ignore::Match::Whitelist(_) => false,
51            },
52        }
53    }
54}