ct_regex_internal/haystack/ext/
hipstr.rs1use std::fmt::{self, Debug};
2use std::hash::{Hash, Hasher};
3use std::ops::Range;
4
5use hipstr::Backend;
6use hipstr::bytes::HipByt;
7use hipstr::string::HipStr;
8
9use crate::haystack::{
10 Haystack, HaystackSlice, IntoHaystack, OwnedHaystackable, first_char, first_char_and_width
11};
12
13impl<'a, B: Backend> HaystackSlice<'a> for HipStr<'a, B> {
14 type Item = char;
15
16 fn slice_with(&self, range: Range<usize>) -> Self {
17 self.slice(range)
18 }
19
20 fn as_bytes(&self) -> &[u8] {
21 HipStr::as_str(self).as_bytes()
22 }
23}
24
25pub struct HipStrStack<'a, B: Backend> {
27 inner: HipStr<'a, B>,
28 index: usize,
29}
30
31impl<'a, B: Backend> IntoHaystack<'a, HipStrStack<'a, B>> for HipStr<'a, B> {
32 fn into_haystack(self) -> HipStrStack<'a, B> {
33 HipStrStack {
34 inner: self,
35 index: 0,
36 }
37 }
38}
39
40impl<'a, B: Backend> Iterator for HipStrStack<'a, B> {
41 type Item = char;
42
43 fn next(&mut self) -> Option<Self::Item> {
44 let (width, first) = first_char_and_width(&self.remainder_as_slice());
45 self.index += width;
47 first
48 }
49}
50
51impl<'a, B: Backend> Haystack<'a> for HipStrStack<'a, B> {
52 type Slice = HipStr<'a, B>;
53
54 fn item(&self) -> Option<Self::Item> {
55 first_char(&self.remainder_as_slice())
56 }
57
58 fn prev_item(&self) -> Option<Self::Item> {
59 let prev_index = self.inner.floor_char_boundary(self.index.checked_sub(1)?);
60 first_char(&self.inner[prev_index..])
61 }
62
63 fn index(&self) -> usize {
64 self.index
65 }
66
67 fn inner_slice(&self) -> Self::Slice {
68 self.inner.clone()
69 }
70
71 fn remainder_as_slice(&self) -> Self::Slice {
72 self.inner.slice(self.index..)
73 }
74
75 fn go_to(&mut self, index: usize) {
76 self.index = index;
77 }
78}
79
80impl<'s, B: Backend> OwnedHaystackable<char> for HipStr<'s, B> {
81 type Hay<'a> = HipStrStack<'a, B> where Self: 'a;
82
83 fn replace_range<'a>(
84 &mut self,
85 range: Range<usize>,
86 with: <Self::Hay<'a> as Haystack<'a>>::Slice
87 ) where Self: 'a {
88 self.mutate().replace_range(range, &with);
89 }
90
91 fn as_haystack<'a>(&'a self) -> Self::Hay<'a> {
92 self.clone().into_haystack()
93 }
94
95 fn as_slice<'a>(&'a self) -> <Self::Hay<'a> as Haystack<'a>>::Slice {
96 self.clone()
97 }
98
99 fn len(&self) -> usize {
100 self.len()
101 }
102}
103
104impl<'a, B: Backend> Debug for HipStrStack<'a, B> {
106 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107 f.debug_struct("HipStrStack")
108 .field("inner", &self.inner)
109 .field("index", &self.index)
110 .finish()
111 }
112}
113
114impl<'a, B: Backend> Clone for HipStrStack<'a, B> {
115 fn clone(&self) -> Self {
116 Self {
117 inner: self.inner.clone(),
118 index: self.index,
119 }
120 }
121}
122
123impl<'a, B: Backend + Hash> Hash for HipStrStack<'a, B> {
124 fn hash<H: Hasher>(&self, state: &mut H) {
125 self.inner.hash(state);
126 self.index.hash(state);
127 }
128}
129
130impl<'a, B: Backend> HaystackSlice<'a> for HipByt<'a, B> {
131 type Item = u8;
132
133 fn slice_with(&self, range: Range<usize>) -> Self {
134 self.slice(range)
135 }
136
137 fn as_bytes(&self) -> &[u8] {
138 HipByt::as_slice(self)
139 }
140}
141
142pub struct HipBytStack<'a, B: Backend> {
144 inner: HipByt<'a, B>,
145 index: usize,
146}
147
148impl<'a, B: Backend> IntoHaystack<'a, HipBytStack<'a, B>> for HipByt<'a, B> {
149 fn into_haystack(self) -> HipBytStack<'a, B> {
150 HipBytStack {
151 inner: self,
152 index: 0,
153 }
154 }
155}
156
157impl<'a, B: Backend> Iterator for HipBytStack<'a, B> {
158 type Item = u8;
159
160 fn next(&mut self) -> Option<Self::Item> {
161 let byte = self.inner.get(self.index).copied();
162
163 if byte.is_some() {
164 self.index += 1;
165 }
166
167 byte
168 }
169}
170
171impl<'a, B: Backend> Haystack<'a> for HipBytStack<'a, B> {
172 type Slice = HipByt<'a, B>;
173
174 fn item(&self) -> Option<Self::Item> {
175 self.inner.get(self.index).copied()
176 }
177
178 fn prev_item(&self) -> Option<Self::Item> {
179 self.inner.get(self.index.checked_sub(1)?).copied()
180 }
181
182 fn index(&self) -> usize {
183 self.index
184 }
185
186 fn inner_slice(&self) -> Self::Slice {
187 self.inner.clone()
188 }
189
190 fn remainder_as_slice(&self) -> Self::Slice {
191 self.inner.slice(self.index..)
192 }
193
194 fn go_to(&mut self, index: usize) {
195 self.index = index;
196 }
197}
198
199impl<'a, B: Backend> Debug for HipBytStack<'a, B> {
200 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
201 f.debug_struct("HipBytStack")
202 .field("inner", &self.inner)
203 .field("index", &self.index)
204 .finish()
205 }
206}
207
208impl<'a, B: Backend> Clone for HipBytStack<'a, B> {
209 fn clone(&self) -> Self {
210 Self {
211 inner: self.inner.clone(),
212 index: self.index,
213 }
214 }
215}
216
217impl<'a, B: Backend + Hash> Hash for HipBytStack<'a, B> {
218 fn hash<H: Hasher>(&self, state: &mut H) {
219 self.inner.hash(state);
220 self.index.hash(state);
221 }
222}
223
224impl<'s, B: Backend> OwnedHaystackable<u8> for HipByt<'s, B> {
225 type Hay<'a> = HipBytStack<'a, B> where Self: 'a;
226
227 fn replace_range<'a>(
228 &mut self,
229 range: Range<usize>,
230 with: <Self::Hay<'a> as Haystack<'a>>::Slice
231 ) where Self: 'a {
232 self.mutate().splice(range, with.iter().copied());
233 }
234
235 fn as_haystack<'a>(&'a self) -> Self::Hay<'a> {
236 self.clone().into_haystack()
237 }
238
239 fn as_slice<'a>(&'a self) -> <Self::Hay<'a> as Haystack<'a>>::Slice {
240 self.clone()
241 }
242
243 fn len(&self) -> usize {
244 self.len()
245 }
246}