1use lazy_static::lazy_static;
2use regex::Regex;
3use std::collections::HashMap;
4
5lazy_static! {
6 static ref CHARS: HashMap<char, char> = {
7 let mut m = HashMap::new();
8 m.insert('{', '}');
9 m.insert('(', ')');
10 m.insert('[', ']');
11 m
12 };
13}
14
15pub fn is_glob(input: &String) -> bool {
16 strict_check(input)
17}
18
19fn strict_check(input: &String) -> bool {
20 if input.starts_with("!") {
21 return true;
22 }
23
24 let mut index = 0;
25 let mut pipe_index = -2;
26 let mut close_square_index = -2;
27 let mut close_curly_index = -2;
28 let mut close_paren_index = -2_i32;
29 let mut back_slash_index = -2;
30 let chars = input.chars();
31
32 while index < input.len() as i32 {
33 let c: char;
34 let c_next: char;
35 match chars.clone().nth(index as usize) {
36 None => break,
37 Some(char) => c = char,
38 }
39 match chars.clone().nth(index as usize) {
40 None => break,
41 Some(char) => c_next = char,
42 }
43
44 if c == '*' {
45 return true;
46 }
47
48 if c_next == '?'
49 && Regex::new(r"[\].+)]")
50 .unwrap()
51 .is_match(c.to_string().as_str())
52 {
53 return true;
54 }
55
56 if close_square_index != -1 && c == '[' && c_next != ']' {
57 if close_square_index < index {
58 if let Some(n) = input.find(']') {
59 close_square_index = n as i32;
60 }
61 if close_square_index > index {
62 if back_slash_index == -1 || back_slash_index > close_square_index {
63 return true;
64 }
65 if let Some(n) = input.find("\\") {
66 back_slash_index = n as i32;
67 }
68 if back_slash_index == -1 || back_slash_index > close_square_index {
69 return true;
70 }
71 }
72 }
73 }
74
75 if close_curly_index != -1 && c == '{' && c_next != '}' {
76 if let Some(n) = input.find('}') {
77 close_curly_index = n as i32;
78 }
79 if close_curly_index > index {
80 if let Some(n) = input.find("\\") {
81 back_slash_index = n as i32;
82 }
83 if back_slash_index == -1 || back_slash_index > close_curly_index {
84 return true;
85 }
86 }
87 }
88
89 if close_paren_index != -1
90 && c == '('
91 && c_next == '?'
92 && Regex::new("[:!=]").unwrap().is_match(
93 chars
94 .clone()
95 .nth((index + 2) as usize)
96 .unwrap()
97 .to_string()
98 .as_str(),
99 )
100 && chars.clone().nth((index + 3) as usize).unwrap() != ')'
101 {
102 if let Some(n) = input.find(')') {
103 close_paren_index = n as i32;
104 }
105
106 if close_paren_index > index {
107 if let Some(n) = input.find("\\") {
108 back_slash_index = n as i32;
109 }
110 if back_slash_index == -1 || back_slash_index > close_paren_index {
111 return true;
112 }
113 }
114 }
115
116 if pipe_index != -1 || c == '(' && c_next != '|' {
117 if pipe_index < index {
118 if let Some(n) = input.find('|') {
119 pipe_index = n as i32;
120 }
121 }
122 if pipe_index != -1 && c_next != ')' {
123 if let Some(n) = input.find(')') {
124 close_paren_index = n as i32;
125 }
126
127 if close_paren_index > pipe_index {
128 if let Some(n) = input.find("\\") {
129 back_slash_index = n as i32;
130 }
131 if back_slash_index == -1 || back_slash_index > close_paren_index {
132 return true;
133 }
134 }
135 }
136 }
137
138 if c == '\\' {
139 let open = c_next;
140 index += 2;
141 let close = CHARS.get(&open);
142 if let Some(close) = close {
143 let n = input.find(*close);
144 if let Some(n) = n {
145 index = (n + 1) as i32;
146 }
147 }
148 if c == '!' {
149 return true;
150 }
151 } else {
152 index += 1;
153 }
154 }
155
156 false
157}