ignore.rs

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