flams_utils/parsing/
read.rs1use crate::{parsing::SourceParser, sourcerefs::StringPosition};
2use std::io::Read;
3
4pub struct ReadParser<R: Read, P: StringPosition> {
5 inner: std::io::Bytes<std::io::BufReader<R>>,
6 buf: Vec<char>,
7 pos: P,
8}
9impl<R: Read, P: StringPosition> ReadParser<R, P> {
10 pub fn new(inner: R) -> Self {
11 Self {
12 inner: std::io::BufReader::new(inner).bytes(),
13 buf: Vec::new(),
14 pos: P::default(),
15 }
16 }
17}
18
19impl<'a, R: Read + 'a, P: StringPosition> SourceParser<'a> for ReadParser<R, P> {
20 type Pos = P;
21 type Str = String;
22 type Source = R;
23 #[inline]
24 fn curr_pos(&self) -> P {
25 self.pos
26 }
27 #[inline]
28 fn skip(&mut self, i: usize) {
29 for _ in 0..i {
30 self.next_char();
31 }
32 }
33 fn next_char(&mut self) -> Option<char> {
34 match self.get_char() {
35 Some('\n') => {
36 self.pos.inc_newline(false);
37 Some('\n')
38 }
39 Some('\r') => {
40 match self.get_char() {
41 Some('\n') | None => {
42 self.pos.inc_newline(false);
43 }
44 Some(c) => {
45 self.pos.inc_newline(false);
46 self.push_char(c);
47 }
48 }
49 Some('\n')
50 }
51 Some(c) => {
52 self.pos.inc_by(c);
53 Some(c)
54 }
55 None => None,
56 }
57 }
58 fn read_until_line_end(&mut self) -> (String, P) {
59 let (s, rn) = self.find_line_end();
60 self.pos.inc_offset_by(&s);
61 let pos = self.pos;
62 if let Some(rn) = rn {
63 self.pos.inc_newline(rn);
64 }
65 (s, pos)
66 }
67 fn trim_start(&mut self) {
68 while let Some(c) = self.get_char() {
69 if c == '\n' {
70 self.pos.inc_newline(false);
71 } else if c == '\r' {
72 match self.get_char() {
73 Some('\n') => {
74 self.pos.inc_newline(true);
75 }
76 Some(c) => {
77 self.push_char(c);
78 self.pos.inc_newline(false);
79 }
80 None => {
81 self.pos.inc_newline(false);
82 break;
83 }
84 }
85 } else if c.is_whitespace() {
86 self.pos.inc_by(c);
87 } else {
88 self.push_char(c);
89 break;
90 }
91 }
92 }
93
94 #[allow(clippy::unnecessary_map_or)]
95 fn starts_with(&mut self, c: char) -> bool {
96 self.get_char().map_or(false, |c2| {
97 self.push_char(c2);
98 c2 == c
99 })
100 }
101 fn read_while(&mut self, mut pred: impl FnMut(char) -> bool) -> Self::Str {
102 let mut ret = String::new();
103 let mut rn = false;
104 while let Some(c) = self.get_char() {
105 if !pred(c) {
106 self.push_char(c);
107 break;
108 }
109 if rn && c == '\n' {
110 self.pos.inc_newline(true);
111 rn = false;
112 continue;
113 }
114 if rn {
115 self.pos.inc_newline(false);
116 rn = false;
117 } else if c == '\n' {
118 self.pos.inc_newline(false);
119 ret.push('\n');
120 continue;
121 } else if c == '\r' {
122 ret.push('\n');
123 rn = true;
124 continue;
125 }
126 self.pos.inc_by(c);
127 ret.push(c);
128 }
129 if rn {
130 self.pos.inc_newline(false);
131 }
132 ret
133 }
134
135 fn read_until_inclusive(&mut self, pred: impl FnMut(char) -> bool) -> Self::Str {
136 let mut r = self.read_until(pred);
137 if let Some(c) = self.next_char() {
138 r.push(c);
139 }
140 r
141 }
142
143 #[inline]
144 fn read_until_byte(&mut self, b: u8) -> Self::Str {
145 self.read_until_char(b as char)
146 }
147 #[inline]
148 fn read_until_char(&mut self, ch: char) -> Self::Str {
149 let mut ret = String::new();
150 let mut rn = false;
151 while let Some(c) = self.get_char() {
152 if c == ch {
153 self.push_char(c);
154 break;
155 }
156 if rn && c == '\n' {
157 self.pos.inc_newline(true);
158 rn = false;
159 continue;
160 }
161 if rn {
162 self.pos.inc_newline(false);
163 rn = false;
164 } else if c == '\n' {
165 self.pos.inc_newline(false);
166 ret.push('\n');
167 continue;
168 } else if c == '\r' {
169 ret.push('\n');
170 rn = true;
171 continue;
172 }
173 self.pos.inc_by(c);
174 ret.push(c);
175 }
176 if rn {
177 self.pos.inc_newline(false);
178 }
179 ret
180 }
181
182 fn read_until_with_brackets(
183 &mut self,
184 open: char,
185 close: char,
186 mut pred: impl FnMut(char) -> bool,
187 ) -> Self::Str {
188 let mut ret = String::new();
189 let mut depth = 0;
190 let mut rn = false;
191 while let Some(c) = self.get_char() {
192 if c == open {
193 depth += 1;
194 self.pos.inc_by(c);
195 ret.push(c);
196 continue;
197 } else if c == close && depth > 0 {
198 depth -= 1;
199 self.pos.inc_by(c);
200 ret.push(c);
201 continue;
202 } else if depth > 0 {
203 if rn && c == '\n' {
204 self.pos.inc_newline(true);
205 rn = false;
206 continue;
207 }
208 if rn {
209 self.pos.inc_newline(false);
210 rn = false;
211 } else if c == '\n' {
212 self.pos.inc_newline(false);
213 ret.push('\n');
214 continue;
215 } else if c == '\r' {
216 ret.push('\n');
217 rn = true;
218 continue;
219 }
220 self.pos.inc_by(c);
221 ret.push(c);
222 continue;
223 }
224 if pred(c) {
225 self.push_char(c);
226 break;
227 }
228 self.pos.inc_by(c);
229 ret.push(c);
230 }
231 if rn {
232 self.pos.inc_newline(false);
233 }
234 ret
235 }
236
237 #[inline]
238 fn read_until_byte_with_brackets(&mut self, b: u8, open: u8, close: u8) -> Self::Str {
239 self.read_until_with_brackets(open as _, close as _, |c| c == b as char)
240 }
241
242 fn peek_head(&mut self) -> Option<char> {
243 self.get_char().inspect(|c| {
244 self.push_char(*c);
245 })
246 }
247 fn read_n(&mut self, i: usize) -> Self::Str {
248 let mut ret = String::new();
249 for _ in 0..i {
250 if let Some(c) = self.next_char() {
251 ret.push(c);
252 } else {
253 break;
254 }
255 }
256 ret
257 }
258
259 fn read_until_str(&mut self, s: &str) -> Self::Str {
260 let mut ret = String::with_capacity(32);
261 while let Some(c) = self.next_char() {
262 ret.push(c);
263 if ret.ends_with(s) {
264 for _ in 0..s.len() {
265 self.push_char(ret.pop().unwrap_or_else(|| unreachable!()));
266 }
267 return ret;
268 }
269 }
270 ret
271 }
272
273 #[inline]
274 fn read_until_needle(&mut self, s: &super::Needle) -> Self::Str {
275 self.read_until_str(s.as_str())
276 }
277
278 fn starts_with_str(&mut self, s: &str) -> bool {
279 let mut read = 0;
280 macro_rules! nope {
281 () => {{
282 for c in s.chars().take(read) {
283 self.push_char(c);
284 }
285 return false;
286 }};
287 }
288 for c in s.chars() {
289 if let Some(c2) = self.next_char() {
290 read += 1;
291 if c != c2 {
292 nope!()
293 }
294 } else {
295 nope!();
296 }
297 }
298 self.buf.extend(s.chars().rev());
299 true
300 }
301
302 fn drop_prefix(&mut self, s: &str) -> bool {
303 let mut read = 0;
304 macro_rules! nope {
305 () => {{
306 for c in s.chars().take(read) {
307 self.push_char(c);
308 }
309 return false;
310 }};
311 }
312 for c in s.chars() {
313 if let Some(c2) = self.next_char() {
314 read += 1;
315 if c != c2 {
316 nope!()
317 }
318 } else {
319 nope!();
320 }
321 }
322 true
323 }
324}
325
326impl<R: Read, P: StringPosition> ReadParser<R, P> {
327 #[inline]
328 fn get_char(&mut self) -> Option<char> {
329 self.buf.pop().or_else(|| self.read_char())
330 }
331 fn read_char(&mut self) -> Option<char> {
332 self.inner.next().and_then(|byte| {
333 byte.ok().and_then(|byte| {
334 if byte & 0b1110_0000_u8 == 192u8 {
335 let next = self.inner.next().and_then(Result::ok)?;
337 Self::char_from_utf8(&[byte, next])
338 } else if byte & 0b1111_0000_u8 == 224u8 {
339 let next1 = self.inner.next().and_then(Result::ok)?;
341 let next2 = self.inner.next().and_then(Result::ok)?;
342 Self::char_from_utf8(&[byte, next1, next2])
343 } else if byte & 0b1111_1000_u8 == 240u8 {
344 let next1 = self.inner.next().and_then(Result::ok)?;
346 let next2 = self.inner.next().and_then(Result::ok)?;
347 let next3 = self.inner.next().and_then(Result::ok)?;
348 Self::char_from_utf8(&[byte, next1, next2, next3])
349 } else {
350 Some(byte as char)
351 }
352 })
353 })
354 }
355 fn push_char(&mut self, c: char) {
356 self.buf.push(c);
357 }
358 fn char_from_utf8(buf: &[u8]) -> Option<char> {
359 std::str::from_utf8(buf).ok().and_then(|s| s.chars().next())
360 }
361 fn find_line_end(&mut self) -> (String, Option<bool>) {
362 let mut ret = String::new();
363 while let Some(c) = self.get_char() {
364 if c == '\n' {
365 return (ret, Some(false));
366 }
367 if c == '\r' {
368 match self.get_char() {
369 Some('\n') => return (ret, Some(true)),
370 Some(c) => self.push_char(c),
371 None => (),
372 }
373 return (ret, Some(true));
374 }
375 ret.push(c);
376 }
377 (ret, None)
378 }
379}