1use super::StringExt;
2
3use std_::mem;
4use std_::str::CharIndices;
5
6#[inline(always)]
7fn next_split<'a, P, T: Eq + Clone>(
8 pred: &mut P,
9 s: &mut &'a str,
10 last: &mut T,
11) -> Option<KeyStr<'a, T>>
12where
13 P: FnMut(char) -> T,
14{
15 let mut next = last.clone();
16 if s.is_empty() {
17 return None;
18 }
19 let end = s
20 .find(|c| {
21 next = pred(c);
22 *last != next
23 })
24 .map_or(s.len(), |v| v);
25 let (ret, new_s) = s.split_at(end);
26 *s = new_s;
27 let key = mem::replace(last, next);
28 Some(KeyStr { str: ret, key })
29}
30
31#[inline(always)]
32fn next_rsplit<'a, P, T: Eq + Clone>(
33 pred: &mut P,
34 s: &mut &'a str,
35 last: &mut T,
36) -> Option<KeyStr<'a, T>>
37where
38 P: FnMut(char) -> T,
39{
40 let mut next = last.clone();
41 if s.is_empty() {
42 return None;
43 }
44 let left = s
45 .rfind(|c| {
46 next = pred(c);
47 *last != next
48 })
49 .map_or(0, |v| s.next_char_boundary(v));
50 let (new_s, ret) = s.split_at(left);
51 *s = new_s;
52 let key = mem::replace(last, next);
53 Some(KeyStr { str: ret, key })
54}
55
56#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
62pub struct KeyStr<'a, T> {
63 pub str: &'a str,
65 pub key: T,
67}
68
69impl<'a, T> KeyStr<'a, T> {
70 pub fn into_pair(self)->(T,&'a str){
72 (self.key,self.str)
73 }
74}
75
76#[derive(Debug, Clone)]
83pub struct SplitWhile<'a, P, T> {
84 pub(super) mapper: P,
85 pub(super) s: &'a str,
86 pub(super) last_left: T,
87 pub(super) last_right: T,
88}
89
90impl<'a, P, T: Eq + Clone> Iterator for SplitWhile<'a, P, T>
91where
92 P: FnMut(char) -> T,
93{
94 type Item = KeyStr<'a, T>;
95 fn next(&mut self) -> Option<Self::Item> {
96 next_split(&mut self.mapper, &mut self.s, &mut self.last_left)
97 }
98}
99
100impl<'a, P, T: Eq + Clone> DoubleEndedIterator for SplitWhile<'a, P, T>
101where
102 P: FnMut(char) -> T,
103{
104 fn next_back(&mut self) -> Option<Self::Item> {
105 next_rsplit(&mut self.mapper, &mut self.s, &mut self.last_right)
106 }
107}
108
109#[derive(Debug, Clone)]
117pub struct RSplitWhile<'a, P, T> {
118 pub(super) mapper: P,
119 pub(super) s: &'a str,
120 pub(super) last_left: T,
121 pub(super) last_right: T,
122}
123
124impl<'a, P, T: Eq + Clone> Iterator for RSplitWhile<'a, P, T>
125where
126 P: FnMut(char) -> T,
127{
128 type Item = KeyStr<'a, T>;
129 fn next(&mut self) -> Option<Self::Item> {
130 next_rsplit(&mut self.mapper, &mut self.s, &mut self.last_right)
131 }
132}
133
134impl<'a, P, T: Eq + Clone> DoubleEndedIterator for RSplitWhile<'a, P, T>
135where
136 P: FnMut(char) -> T,
137{
138 fn next_back(&mut self) -> Option<Self::Item> {
139 next_split(&mut self.mapper, &mut self.s, &mut self.last_left)
140 }
141}
142
143#[derive(Clone, Debug)]
157pub struct CharIndicesFrom<'a> {
158 pub(super) offset: usize,
159 pub(super) iter: CharIndices<'a>,
160}
161
162impl<'a> Iterator for CharIndicesFrom<'a> {
163 type Item = (usize, char);
164
165 #[inline]
166 fn next(&mut self) -> Option<(usize, char)> {
167 self.iter.next().map(|(i, c)| (i + self.offset, c))
168 }
169
170 #[inline]
171 fn count(self) -> usize {
172 self.iter.count()
173 }
174
175 #[inline]
176 fn size_hint(&self) -> (usize, Option<usize>) {
177 self.iter.size_hint()
178 }
179
180 #[inline]
181 fn last(mut self) -> Option<(usize, char)> {
182 self.next_back()
183 }
184}
185
186impl<'a> DoubleEndedIterator for CharIndicesFrom<'a> {
187 #[inline]
188 fn next_back(&mut self) -> Option<(usize, char)> {
189 self.iter.next_back().map(|(i, c)| (i + self.offset, c))
190 }
191}
192
193impl<'a> CharIndicesFrom<'a> {
194 pub fn as_str(&self) -> &'a str {
196 self.iter.as_str()
197 }
198}