filenamegen/
token.rs

1#[derive(Debug)]
2pub enum Token {
3    Literal(char),
4    /// `?`
5    Any,
6    /// `*`
7    ZeroOrMore,
8    /// `{`
9    StartAlternative,
10    /// `,`
11    NextAlternative,
12    /// `}`
13    EndAlternative,
14    /// `[`
15    StartClass,
16    /// `!`
17    NegateClass,
18    /// `]`
19    EndClass,
20    ClassContent(char),
21}
22
23impl Token {
24    /// Append a regex representation of Token to the supplied pattern string
25    pub fn append_regex(&self, pattern: &mut String, is_first_in_component: bool) {
26        match self {
27            Token::Literal(c) => pattern.push_str(&regex::escape(&c.to_string())),
28            // `?` matches any single character, except for `.` at the start of
29            // a filename.
30            Token::Any => {
31                if is_first_in_component {
32                    #[cfg(not(windows))]
33                    pattern.push_str("[^./]");
34                    #[cfg(windows)]
35                    pattern.push_str("[^./\\\\]");
36                } else {
37                    #[cfg(not(windows))]
38                    pattern.push_str("[^/]");
39                    #[cfg(windows)]
40                    pattern.push_str("[^/\\\\]");
41                }
42            }
43            // `*` matches 0 or more of any character,
44            // except for `.` at the start of a filename.
45            Token::ZeroOrMore => {
46                if is_first_in_component {
47                    #[cfg(not(windows))]
48                    pattern.push_str("[^./][^/]*");
49                    #[cfg(windows)]
50                    pattern.push_str("[^./\\\\][^/\\\\]*");
51                } else {
52                    #[cfg(not(windows))]
53                    pattern.push_str("[^/]*");
54                    #[cfg(windows)]
55                    pattern.push_str("[^/\\\\]*");
56                }
57            }
58            Token::StartAlternative => pattern.push('('),
59            Token::NextAlternative => pattern.push('|'),
60            Token::EndAlternative => pattern.push(')'),
61            Token::StartClass => pattern.push('['),
62            Token::NegateClass => pattern.push('^'),
63            Token::EndClass => pattern.push(']'),
64            Token::ClassContent(c) => pattern.push(*c),
65        }
66    }
67}