1mod tests;
2
3pub trait Haystack {
7 fn pattern_table(needle: &[u8]) -> Vec<usize> {
9 let mut i = 0;
10 let mut j = 1;
11 let mut arr = vec![0; needle.len()];
12 while j < needle.len() {
13 if needle[i] == needle[j] {
14 i += 1;
15 arr[j] = i;
16 j += 1;
17 } else {
18 if i != 0 {
19 i = arr[i - 1];
20 } else {
21 arr[j] = i;
22 j += 1;
23 }
24 }
25 }
26 arr
27 }
28
29 fn contains_needle<N: AsRef<[u8]>>(&self, needle: N) -> bool;
31
32 fn first_indexof_needle<N: AsRef<[u8]>>(&self, needle: N) -> Option<usize>;
34
35 fn last_indexof_needle<N: AsRef<[u8]>>(&self, needle: N) -> Option<usize>;
37
38 fn indexesof_needle<N: AsRef<[u8]>>(&self, needle: N) -> Option<Vec<usize>>;
40}
41
42impl<H: AsRef<[u8]>> Haystack for H {
44 fn contains_needle<N: AsRef<[u8]>>(&self, needle: N) -> bool {
45 let needle = needle.as_ref();
46 let pattern_table = Self::pattern_table(needle);
47 let haystack = &self.as_ref();
48
49 let mut haystack_c = 0usize;
50 let mut needle_c = 0usize;
51
52 let haystack_len = haystack.len();
53 let needle_len = needle.len();
54
55 while haystack_c < haystack_len {
56 if haystack[haystack_c] == needle[needle_c] {
57 haystack_c += 1;
58 needle_c += 1;
59 }
60 if needle_c == needle_len {
61 return true;
62 } else {
63 if haystack_c < haystack_len && haystack[haystack_c] != needle[needle_c] {
64 if needle_c != 0 {
65 needle_c = pattern_table[needle_c - 1];
66 } else {
67 haystack_c += 1;
68 }
69 }
70 }
71 }
72 false
73 }
74
75 fn first_indexof_needle<N: AsRef<[u8]>>(&self, needle: N) -> Option<usize> {
76 let needle = needle.as_ref();
77 let pattern_table = Self::pattern_table(needle);
78 let haystack = &self.as_ref();
79
80 let mut haystack_c = 0usize;
81 let mut needle_c = 0usize;
82
83 let haystack_len = haystack.len();
84 let needle_len = needle.len();
85
86 while haystack_c < haystack_len {
87 if haystack[haystack_c] == needle[needle_c] {
88 haystack_c += 1;
89 needle_c += 1;
90 }
91 if needle_c == needle_len {
92 return Some(haystack_c - needle_len);
93 } else {
94 if haystack_c < haystack_len && haystack[haystack_c] != needle[needle_c] {
95 if needle_c != 0 {
96 needle_c = pattern_table[needle_c - 1];
97 } else {
98 haystack_c += 1;
99 }
100 }
101 }
102 }
103 None
104 }
105
106 fn last_indexof_needle<N: AsRef<[u8]>>(&self, needle: N) -> Option<usize> {
107 let needle = needle.as_ref();
108 let pattern_table = Self::pattern_table(needle);
109 let haystack = &self.as_ref();
110
111 let mut haystack_c = 0usize;
112 let mut needle_c = 0usize;
113
114 let haystack_len = haystack.len();
115 let needle_len = needle.len();
116
117 let mut index: Option<usize> = None;
118
119 while haystack_c < haystack_len {
120 if haystack[haystack_c] == needle[needle_c] {
121 haystack_c += 1;
122 needle_c += 1;
123 }
124 if needle_c == needle_len {
125 index = Some(haystack_c - needle_len);
126 needle_c = 0;
127 } else {
128 if haystack_c < haystack_len && haystack[haystack_c] != needle[needle_c] {
129 if needle_c != 0 {
130 needle_c = pattern_table[needle_c - 1];
131 } else {
132 haystack_c += 1;
133 }
134 }
135 }
136 }
137 index
138 }
139
140 fn indexesof_needle<N: AsRef<[u8]>>(&self, needle: N) -> Option<Vec<usize>> {
141 let needle = needle.as_ref();
142 let pattern_table = Self::pattern_table(needle);
143 let haystack = &self.as_ref();
144
145 let mut haystack_c = 0usize;
146 let mut needle_c = 0usize;
147
148 let haystack_len = haystack.len();
149 let needle_len = needle.len();
150
151 let mut indexes = Vec::new();
152
153 while haystack_c < haystack_len {
154 if haystack[haystack_c] == needle[needle_c] {
155 haystack_c += 1;
156 needle_c += 1;
157 }
158 if needle_c == needle_len {
159 indexes.push(haystack_c - needle_len);
160 needle_c = 0;
161 } else {
162 if haystack_c < haystack_len && haystack[haystack_c] != needle[needle_c] {
163 if needle_c != 0 {
164 needle_c = pattern_table[needle_c - 1];
165 } else {
166 haystack_c += 1;
167 }
168 }
169 }
170 }
171 if indexes.len() > 0 {
172 Some(indexes)
173 } else {
174 None
175 }
176 }
177}