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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#[cfg(feature = "include-exclude")]
use globset::{Glob, GlobMatcher};

#[derive(Debug)]
pub struct Config {
    #[cfg(feature = "include-exclude")]
    include: Vec<GlobMatcher>,
    #[cfg(feature = "include-exclude")]
    exclude: Vec<GlobMatcher>,
    gzip: bool,
    br: bool,
}

impl Default for Config {
    fn default() -> Self {
        Self {
            #[cfg(feature = "include-exclude")]
            include: vec![],
            #[cfg(feature = "include-exclude")]
            exclude: vec![],
            gzip: true,
            br: true,
        }
    }
}

impl Config {
    pub fn new() -> Self {
        Self::default()
    }

    // Builder functions
    #[cfg(feature = "include-exclude")]
    pub fn add_include(&mut self, pattern: String) {
        self.include.push(
            Glob::new(&pattern)
                .expect("Failed to parse glob pattern for include")
                .compile_matcher(),
        );
    }

    #[cfg(feature = "include-exclude")]
    pub fn add_exclude(&mut self, pattern: String) {
        self.exclude.push(
            Glob::new(&pattern)
                .expect("Failed to parse glob pattern for exclude")
                .compile_matcher(),
        );
    }

    pub fn set_gzip(&mut self, status: bool) {
        self.gzip = status;
    }

    pub fn set_br(&mut self, status: bool) {
        self.br = status;
    }

    #[cfg(feature = "include-exclude")]
    pub fn get_includes(&self) -> &Vec<GlobMatcher> {
        &self.include
    }

    #[cfg(feature = "include-exclude")]
    pub fn get_excludes(&self) -> &Vec<GlobMatcher> {
        &self.exclude
    }

    /// Check if a file at some path should be included based on this config.
    ///
    /// When deciding, includes always have priority over excludes. That means
    /// you typically will list paths you want excluded, then add includes to
    /// make an exception for some subset of files.
    #[allow(unused_variables)]
    pub fn should_include(&self, path: &str) -> bool {
        #[cfg(feature = "include-exclude")]
        {
            // Includes have priority.
            self.include
            .iter()
            .any(|include| include.is_match(path))
            // If not, then we check if the file has been excluded. Any file
            // that is not explicitly excluded will be 
            || !self
                .exclude
                .iter()
                .any(|exclude| exclude.is_match(path))
        }
        #[cfg(not(feature = "include-exclude"))]
        {
            true
        }
    }

    pub fn should_gzip(&self) -> bool {
        self.gzip
    }

    pub fn should_br(&self) -> bool {
        self.br
    }
}