1use std::fmt::Debug;
17use std::iter::Iterator;
18
19use super::{InputIter, Offsetable, Positioned, Seekable, Span, SpanRange};
20
21#[derive(Debug)]
23pub struct SliceIter<'a, T: Debug + 'a> {
24 source: &'a [T],
25 offset: usize,
26}
27
28impl<'a, T: Debug + 'a> SliceIter<'a, T> {
29 pub fn new(source: &'a [T]) -> Self {
31 SliceIter {
32 source: source,
33 offset: 0,
34 }
35 }
36}
37
38impl<'a, T: Debug + 'a> Iterator for SliceIter<'a, T> {
39 type Item = &'a T;
40
41 fn next(&mut self) -> Option<Self::Item> {
42 match self.source.get(self.offset) {
43 Some(item) => {
44 self.offset += 1;
45 Some(item)
46 }
47 None => None,
48 }
49 }
50}
51
52impl<'a, T: Debug + 'a> Offsetable for SliceIter<'a, T> {
53 fn get_offset(&self) -> usize {
54 self.offset
55 }
56}
57
58impl<'a, It> Positioned for SliceIter<'a, It>
59where
60 It: Positioned + Debug,
61{
62 fn line(&self) -> usize {
63 match self.peek_next() {
64 Some(i) => i.line(),
65 None => 0,
66 }
67 }
68
69 fn column(&self) -> usize {
70 match self.peek_next() {
71 Some(i) => i.column(),
72 None => 0,
73 }
74 }
75}
76
77impl<'a, T: Debug + 'a> Clone for SliceIter<'a, T> {
78 fn clone(&self) -> Self {
79 SliceIter {
80 source: self.source,
81 offset: self.offset,
82 }
83 }
84}
85
86impl<'a, T: Debug + 'a> InputIter for SliceIter<'a, T> {
87 fn curr(&self) -> Self::Item {
88 if self.offset >= self.source.len() {
89 self.source.get(self.source.len() - 1).unwrap()
90 } else {
91 if self.offset == 0 {
92 self.source.get(self.offset).unwrap()
93 } else {
94 self.source.get(self.offset - 1).unwrap()
95 }
96 }
97 }
98}
99
100impl<'a, T: Debug + 'a> Span<&'a [T]> for SliceIter<'a, T> {
101 fn span(&self, idx: SpanRange) -> &'a [T] {
102 match idx {
103 SpanRange::Range(r) => self.source.index(r),
104 SpanRange::RangeTo(r) => self.source.index(r),
105 SpanRange::RangeFrom(r) => self.source.index(r),
106 SpanRange::RangeFull(r) => self.source.index(r),
107 }
108 }
109}
110
111impl<'a> From<&'a str> for SliceIter<'a, u8> {
112 fn from(source: &'a str) -> Self {
113 SliceIter::new(source.as_bytes())
114 }
115}
116
117impl<'a, T: Debug> From<&'a [T]> for SliceIter<'a, T> {
118 fn from(source: &'a [T]) -> Self {
119 SliceIter::new(source)
120 }
121}
122
123impl<'a, T: Debug> From<&'a Vec<T>> for SliceIter<'a, T> {
124 fn from(source: &'a Vec<T>) -> Self {
125 SliceIter::new(source.as_slice())
126 }
127}
128
129impl<'a, O: Debug> Peekable<&'a O> for SliceIter<'a, O> {
130 fn peek_next(&self) -> Option<&'a O> {
131 self.source.get(self.offset)
132 }
133}
134
135#[derive(Debug)]
137pub struct StrIter<'a> {
138 source: &'a str,
139 offset: usize,
140 line: usize,
141 column: usize,
142}
143
144impl<'a> StrIter<'a> {
145 pub fn new(source: &'a str) -> Self {
147 StrIter {
148 source: source,
149 offset: 0,
150 line: 1,
151 column: 1,
152 }
153 }
154}
155
156impl<'a> Iterator for StrIter<'a> {
157 type Item = &'a u8;
158
159 fn next(&mut self) -> Option<Self::Item> {
160 match self.source.as_bytes().get(self.offset) {
161 Some(item) => {
163 self.offset += 1;
164 if *item == b'\n' {
165 self.line += 1;
166 self.column = 1;
167 } else {
168 self.column += 1;
169 }
170 Some(item)
171 }
172 None => None,
173 }
174 }
175}
176
177impl<'a> Offsetable for StrIter<'a> {
178 fn get_offset(&self) -> usize {
179 self.offset
180 }
181}
182
183impl<'a> Positioned for StrIter<'a> {
184 fn line(&self) -> usize {
185 self.line
186 }
187
188 fn column(&self) -> usize {
189 self.column
190 }
191}
192
193impl<'a> Clone for StrIter<'a> {
194 fn clone(&self) -> Self {
195 StrIter {
196 source: self.source,
197 offset: self.offset,
198 line: self.line,
199 column: self.column,
200 }
201 }
202}
203
204impl<'a> InputIter for StrIter<'a> {
205 fn curr(&self) -> Self::Item {
206 if self.offset >= self.source.len() {
207 self.source.as_bytes().get(self.source.len() - 1).unwrap()
208 } else {
209 if self.offset == 0 {
210 self.source.as_bytes().get(self.offset).unwrap()
211 } else {
212 self.source.as_bytes().get(self.offset - 1).unwrap()
213 }
214 }
215 }
216}
217
218impl<'a> From<&'a str> for StrIter<'a> {
219 fn from(source: &'a str) -> Self {
220 Self::new(source)
221 }
222}
223
224use std::ops::Index;
225
226impl<'a> Span<&'a str> for StrIter<'a> {
227 fn span(&self, idx: SpanRange) -> &'a str {
228 match idx {
229 SpanRange::Range(r) => self.source.index(r),
230 SpanRange::RangeTo(r) => self.source.index(r),
231 SpanRange::RangeFrom(r) => self.source.index(r),
232 SpanRange::RangeFull(r) => self.source.index(r),
233 }
234 }
235}
236
237impl<'a> Seekable for StrIter<'a> {
238 fn seek(&mut self, to: usize) -> usize {
239 let self_len = self.source.len();
240 let offset = if self_len > to { to } else { self_len };
241 self.offset = offset;
242 self.offset
243 }
244}
245
246use super::Peekable;
247
248impl<'a> Peekable<&'a u8> for StrIter<'a> {
249 fn peek_next(&self) -> Option<&'a u8> {
250 self.source.as_bytes().get(self.offset)
251 }
252}