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
103
104
105
106
107
108
109
110
#[inline(always)]
fn cend(s: &str) -> bool {
s.is_empty() || s.starts_with('/')
}
#[inline(always)]
fn cwild(s: &str) -> bool {
s.starts_with('*')
}
#[inline(always)]
fn cnext(s: &str) -> &str {
&s[1..]
}
#[inline(always)]
fn cequal(s1: &str, s2: &str) -> bool {
s1.starts_with(&s2[0..1])
}
macro_rules! DEFINE_INTERSECT {
($name:ident, $end:ident, $wild:ident, $next:ident, $elem_intersect:ident) => {
fn $name(c1: &str, c2: &str) -> bool {
if ($end(c1) && $end(c2)) {
return true;
}
if ($wild(c1) && $end(c2)) {
return $name($next(c1), c2);
}
if ($end(c1) && $wild(c2)) {
return $name(c1, $next(c2));
}
if ($wild(c1)) {
if ($end($next(c1))) {
return true;
}
if ($name($next(c1), c2)) {
return true;
} else {
return $name(c1, $next(c2));
}
}
if ($wild(c2)) {
if ($end($next(c2))) {
return true;
}
if ($name($next(c1), c2)) {
return true;
} else {
return $name(c1, $next(c2));
}
}
if ($end(c1) || $end(c2)) {
return false;
}
if ($elem_intersect(c1, c2)) {
return $name($next(c1), $next(c2));
}
return false;
}
};
}
DEFINE_INTERSECT!(sub_chunk_intersect, cend, cwild, cnext, cequal);
#[inline(always)]
fn chunk_intersect(c1: &str, c2: &str) -> bool {
if (cend(c1) && !cend(c2)) || (!cend(c1) && cend(c2)) {
return false;
}
sub_chunk_intersect(c1, c2)
}
#[inline(always)]
fn end(s: &str) -> bool {
s.is_empty()
}
#[inline(always)]
fn wild(s: &str) -> bool {
s.starts_with("**/") || s == "**"
}
#[inline(always)]
fn next(s: &str) -> &str {
match s.find('/') {
Some(idx) => &s[(idx + 1)..],
None => "",
}
}
DEFINE_INTERSECT!(res_intersect, end, wild, next, chunk_intersect);
#[inline(always)]
pub fn intersect(s1: &str, s2: &str) -> bool {
res_intersect(s1, s2)
}