1
2
3#![no_std]
4
5pub trait SplitBefore<'a, T: 'a, P> {
21 fn split_before(&self, predicate: P) -> SplitInc<'a, T, P>;
22}
23
24impl <'a, T: 'a, P> SplitBefore<'a, T, P> for &'a [T]
25where
26 P: FnMut(&T) -> bool,
27 T: core::fmt::Debug,
28{
29 fn split_before(&self, predicate: P) -> SplitInc<'a, T, P> {
30 SplitInc::split_before(&self, predicate)
31 }
32}
33
34pub trait SplitAfter<'a, T: 'a, P> {
50 fn split_after(&self, predicate: P) -> SplitInc<'a, T, P>;
51}
52
53impl <'a, T: 'a, P> SplitAfter<'a, T, P> for &'a [T]
54where
55 P: FnMut(&T) -> bool,
56 T: core::fmt::Debug,
57{
58 fn split_after(&self, predicate: P) -> SplitInc<'a, T, P> {
59 SplitInc::split_after(&self, predicate)
60 }
61}
62
63pub struct SplitInc<'a, T: 'a, F> {
64 index: usize,
65 data: &'a [T],
66 matcher: F,
67 mode: Mode,
68}
69
70enum Mode {
71 Before,
72 After,
73}
74
75impl <'a, T, F> SplitInc<'a, T, F>
76where
77 F: FnMut(&T) -> bool,
78 T: core::fmt::Debug,
79{
80 pub fn split_before(data: &'a [T], matcher: F) -> Self {
81 SplitInc{ index: 0, data, matcher, mode: Mode::Before }
82 }
83
84 pub fn split_after(data: &'a [T], matcher: F) -> Self {
85 SplitInc{ index: 0, data, matcher, mode: Mode::After }
86 }
87
88 fn iter_before(&mut self) -> Option<&'a [T]> {
89 if self.index == self.data.len() {
91 return None
92 }
93
94 let index = self.index;
96
97 for i in index..self.data.len() {
98
99 if (self.matcher)(&self.data[i]) {
100 if i == index && i < self.data.len() - 1 {
103 continue
104 } else if i == index {
107 self.index = self.data.len();
108 return Some(&self.data[index..])
109 }
110
111 self.index = i;
113 return Some(&self.data[index..i])
114 }
115
116 if i == (self.data.len() - 1) {
118 self.index = self.data.len();
119 return Some(&self.data[index..])
120 }
121 }
122
123 None
124 }
125
126 fn iter_after(&mut self) -> Option<&'a [T]> {
127 if self.index == self.data.len() {
129 return None
130 }
131
132 let index = self.index;
134
135 for i in index..self.data.len() {
136
137 if (self.matcher)(&self.data[i]) {
139 self.index = i+1;
140 return Some(&self.data[index..i+1])
141 }
142
143 if i == (self.data.len() - 1) {
145 self.index = self.data.len();
146 return Some(&self.data[index..])
147 }
148 }
149
150 None
151 }
152}
153
154impl <'a, T, F> Iterator for SplitInc<'a, T, F>
155where
156 F: FnMut(&T) -> bool,
157 T: core::fmt::Debug,
158{
159 type Item = &'a [T];
160
161 fn next(&mut self) -> Option<Self::Item> {
162
163 match self.mode {
164 Mode::Before => self.iter_before(),
165 Mode::After => self.iter_after(),
166 }
167 }
168}
169
170#[cfg(test)]
171mod tests {
172 use super::*;
173
174 #[test]
175 fn test_split_before() {
176 let a: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
177
178 let mut s = (&a[..]).split_before(|v| *v == 2 || *v == 5);
179
180 assert_eq!(s.next().unwrap(), &[0, 1]);
181 assert_eq!(s.next().unwrap(), &[2, 3, 4]);
182 assert_eq!(s.next().unwrap(), &[5, 6, 7, 8]);
183 assert_eq!(s.next().is_none(), true);
184 }
185
186 #[test]
187 fn test_split_before_no_match() {
188 let a: &[u8] = &[0, 1, 2];
189
190 let mut s = SplitInc::split_before(&a, |v| *v == 12);
191
192 assert_eq!(s.next().unwrap(), &[0, 1, 2]);
193 assert_eq!(s.next().is_none(), true);
194 }
195
196 #[test]
197 fn test_split_before_start() {
198 let a: &[u8] = &[0, 1, 2];
199
200 let mut s = SplitInc::split_before(&a, |v| *v == 0 );
201
202 assert_eq!(s.next().unwrap(), &[0, 1, 2]);
203 assert_eq!(s.next().is_none(), true);
204 }
205
206 #[test]
207 fn test_split_before_end() {
208 let a: &[u8] = &[0, 1, 2];
209
210 let mut s = SplitInc::split_before(&a, |v| *v == 2 );
211
212 assert_eq!(s.next().unwrap(), &[0, 1]);
213 assert_eq!(s.next().unwrap(), &[2]);
214 assert_eq!(s.next().is_none(), true);
215 }
216
217 #[test]
218 fn test_split_after() {
219 let a: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
220
221 let mut s = SplitInc::split_after(&a, |v| *v == 2 || *v == 5);
222
223 assert_eq!(s.next().unwrap(), &[0, 1, 2]);
224 assert_eq!(s.next().unwrap(), &[3, 4, 5]);
225 assert_eq!(s.next().unwrap(), &[6, 7, 8]);
226 assert_eq!(s.next().is_none(), true);
227 }
228
229 #[test]
230 fn test_split_after_no_match() {
231 let a: &[u8] = &[0, 1, 2];
232
233 let mut s = SplitInc::split_after(&a, |v| *v == 12);
234
235 assert_eq!(s.next().unwrap(), &[0, 1, 2]);
236 assert_eq!(s.next().is_none(), true);
237 }
238
239 #[test]
240 fn test_split_after_start() {
241 let a: &[u8] = &[0, 1, 2];
242
243 let mut s = SplitInc::split_after(&a, |v| *v == 0 );
244
245 assert_eq!(s.next().unwrap(), &[0]);
246 assert_eq!(s.next().unwrap(), &[1, 2]);
247 assert_eq!(s.next().is_none(), true);
248 }
249
250 #[test]
251 fn test_split_after_end() {
252 let a: &[u8] = &[0, 1, 2];
253
254 let mut s = SplitInc::split_after(&a, |v| *v == 2 );
255
256 assert_eq!(s.next().unwrap(), &[0, 1, 2]);
257 assert_eq!(s.next().is_none(), true);
258 }
259}
260