Skip to main content

scanner_rust/
scanner.rs

1use std::{
2    char::REPLACEMENT_CHARACTER,
3    fs::File,
4    io::Read,
5    path::Path,
6    str::{FromStr, from_utf8},
7};
8
9use educe::Educe;
10use utf8_width::*;
11
12use crate::{
13    ScannerError,
14    kmp::compute_lps,
15    reader::read,
16    text::{into_string_lossy, numeric_text},
17    whitespaces::*,
18};
19
20/// A simple text scanner which can parse primitive types and strings using UTF-8.
21#[derive(Educe)]
22#[educe(Debug)]
23pub struct Scanner<R: Read, const N: usize = 256> {
24    #[educe(Debug(ignore))]
25    reader:       R,
26    buf:          [u8; N],
27    buf_length:   usize,
28    buf_offset:   usize,
29    passing_byte: Option<u8>,
30}
31
32impl<R: Read> Scanner<R> {
33    /// Create a scanner from a reader.
34    ///
35    /// ```rust
36    /// use std::io;
37    ///
38    /// use scanner_rust::Scanner;
39    ///
40    /// let mut sc = Scanner::new(io::stdin());
41    /// ```
42    #[inline]
43    pub fn new(reader: R) -> Scanner<R> {
44        Self::new2(reader)
45    }
46}
47
48impl<R: Read, const N: usize> Scanner<R, N> {
49    /// Create a scanner from a reader and set the buffer size via generics.
50    ///
51    /// The buffer size `N` must be at least 4 bytes.
52    ///
53    /// ```rust
54    /// use std::io;
55    ///
56    /// use scanner_rust::Scanner;
57    ///
58    /// let mut sc: Scanner<_, 1024> = Scanner::new2(io::stdin());
59    /// ```
60    #[inline]
61    pub fn new2(reader: R) -> Scanner<R, N> {
62        // The buffer must be at least 4 bytes to hold a full UTF-8 character.
63        const { assert!(N >= 4, "the buffer size N must be at least 4 bytes") };
64
65        Scanner {
66            reader,
67            buf: [0u8; N],
68            buf_length: 0,
69            buf_offset: 0,
70            passing_byte: None,
71        }
72    }
73}
74
75impl Scanner<File> {
76    /// Create a scanner to read data from a file by its path.
77    ///
78    /// ```rust
79    /// use scanner_rust::Scanner;
80    ///
81    /// let mut sc = Scanner::scan_path("Cargo.toml").unwrap();
82    /// ```
83    #[inline]
84    pub fn scan_path<P: AsRef<Path>>(path: P) -> Result<Scanner<File>, ScannerError> {
85        Self::scan_path2(path)
86    }
87}
88
89impl<const N: usize> Scanner<File, N> {
90    /// Create a scanner to read data from a file by its path and set the buffer size via generics.
91    ///
92    /// The buffer size `N` must be at least 4 bytes.
93    ///
94    /// ```rust
95    /// use scanner_rust::Scanner;
96    ///
97    /// let mut sc: Scanner<_, 1024> = Scanner::scan_path2("Cargo.toml").unwrap();
98    /// ```
99    #[inline]
100    pub fn scan_path2<P: AsRef<Path>>(path: P) -> Result<Scanner<File, N>, ScannerError> {
101        let reader = File::open(path)?;
102
103        Ok(Scanner::new2(reader))
104    }
105}
106
107impl<R: Read, const N: usize> Scanner<R, N> {
108    #[inline]
109    fn buf_align_to_front_end(&mut self) {
110        self.buf.copy_within(self.buf_offset..(self.buf_offset + self.buf_length), 0);
111
112        self.buf_offset = 0;
113    }
114
115    #[inline]
116    fn buf_left_shift(&mut self, distance: usize) {
117        debug_assert!(self.buf_length >= distance);
118
119        self.buf_offset += distance;
120        self.buf_length -= distance;
121
122        if self.buf_offset >= N - 4 {
123            self.buf_align_to_front_end();
124        }
125    }
126
127    /// Left shift (if necessary) the buffer to remove bytes from the start of the buffer. Typically, you should use this after `peek`ing the buffer.
128    ///
129    /// # Safety
130    ///
131    /// `number_of_bytes` must not be greater than the length of the currently buffered data (the length of the slice returned by `peek`). A larger value underflows the internal buffer length and causes out-of-bounds access afterwards.
132    #[inline]
133    pub unsafe fn remove_heading_bytes_from_buffer(&mut self, number_of_bytes: usize) {
134        self.buf_left_shift(number_of_bytes);
135    }
136
137    #[inline]
138    fn buf_skip_line(&mut self, line_length: usize) {
139        let ending = if self.buf[self.buf_offset + line_length] == b'\n' { b'\r' } else { b'\n' };
140        let mut consumed = line_length + 1;
141
142        if consumed == self.buf_length {
143            // Defer the second byte when a line ending is split across reads.
144            self.passing_byte = Some(ending);
145        } else if self.buf[self.buf_offset + consumed] == ending {
146            consumed += 1;
147        }
148
149        self.buf_left_shift(consumed);
150    }
151
152    #[inline]
153    fn buf_fill_char(&mut self, width: usize) -> Result<usize, ScannerError> {
154        while self.buf_length < width {
155            let size =
156                read(&mut self.reader, &mut self.buf[(self.buf_offset + self.buf_length)..])?;
157
158            if size == 0 {
159                // A sequence cut off by the end of data is handled one byte at a time.
160                return Ok(1);
161            }
162
163            self.buf_length += size;
164        }
165
166        Ok(width)
167    }
168
169    #[inline]
170    fn buf_raw_char_width(&mut self) -> Result<usize, ScannerError> {
171        let width = get_width(self.buf[self.buf_offset]);
172
173        if width <= 1 || self.buf_fill_char(width)? == 1 {
174            return Ok(1);
175        }
176
177        // A broken sequence must not skip over a whitespace byte.
178        if self.buf[(self.buf_offset + 1)..(self.buf_offset + width)]
179            .iter()
180            .all(|byte| byte & 0xC0 == 0x80)
181        {
182            Ok(width)
183        } else {
184            Ok(1)
185        }
186    }
187
188    // Force inlining because this runs for every multi-byte character in hot loops.
189    #[inline(always)]
190    fn buf_push_char(&mut self, temp: &mut String, width: usize) {
191        match from_utf8(&self.buf[self.buf_offset..(self.buf_offset + width)]) {
192            Ok(char_str) => {
193                temp.push_str(char_str);
194
195                self.buf_left_shift(width);
196            },
197            Err(_) => {
198                temp.push(REPLACEMENT_CHARACTER);
199
200                self.buf_left_shift(1);
201            },
202        }
203    }
204
205    fn passing_read(&mut self) -> Result<bool, ScannerError> {
206        if self.buf_length == 0 {
207            let size = read(&mut self.reader, &mut self.buf[self.buf_offset..])?;
208
209            if size == 0 {
210                return Ok(false);
211            }
212
213            self.buf_length += size;
214
215            if let Some(passing_byte) = self.passing_byte.take()
216                && self.buf[self.buf_offset] == passing_byte
217            {
218                self.buf_left_shift(1);
219
220                return if size == 1 {
221                    let size = read(&mut self.reader, &mut self.buf[self.buf_offset..])?;
222
223                    if size == 0 {
224                        Ok(false)
225                    } else {
226                        self.buf_length += size;
227
228                        Ok(true)
229                    }
230                } else {
231                    Ok(true)
232                };
233            }
234
235            Ok(true)
236        } else {
237            Ok(true)
238        }
239    }
240}
241
242impl<R: Read, const N: usize> Scanner<R, N> {
243    /// Read the next char. If the data is not a correct char, it will return a `Ok(Some(REPLACEMENT_CHARACTER))` which is �. If there is nothing to read, it will return `Ok(None)`.
244    ///
245    /// ```rust
246    /// use scanner_rust::Scanner;
247    ///
248    /// let mut sc = Scanner::new("5 c 中文".as_bytes());
249    ///
250    /// assert_eq!(Some('5'), sc.next_char().unwrap());
251    /// assert_eq!(Some(' '), sc.next_char().unwrap());
252    /// assert_eq!(Some('c'), sc.next_char().unwrap());
253    /// assert_eq!(Some(' '), sc.next_char().unwrap());
254    /// assert_eq!(Some('中'), sc.next_char().unwrap());
255    /// assert_eq!(Some('文'), sc.next_char().unwrap());
256    /// assert_eq!(None, sc.next_char().unwrap());
257    /// ```
258    pub fn next_char(&mut self) -> Result<Option<char>, ScannerError> {
259        if !self.passing_read()? {
260            return Ok(None);
261        }
262
263        let e = self.buf[self.buf_offset];
264
265        let width = get_width(e);
266
267        match width {
268            0 => {
269                self.buf_left_shift(1);
270
271                Ok(Some(REPLACEMENT_CHARACTER))
272            },
273            1 => {
274                self.buf_left_shift(1);
275
276                Ok(Some(e as char))
277            },
278            _ => {
279                let width = self.buf_fill_char(width)?;
280                let char_str_bytes = &self.buf[self.buf_offset..(self.buf_offset + width)];
281
282                match from_utf8(char_str_bytes) {
283                    Ok(char_str) => {
284                        let c = char_str.chars().next();
285
286                        self.buf_left_shift(width);
287
288                        Ok(c)
289                    },
290                    Err(_) => {
291                        self.buf_left_shift(1);
292
293                        Ok(Some(REPLACEMENT_CHARACTER))
294                    },
295                }
296            },
297        }
298    }
299
300    /// Read the next line but not include the trailing line character (or line characters like `CrLf`(`\r\n`)). If there is nothing to read, it will return `Ok(None)`.
301    ///
302    /// ```rust
303    /// use scanner_rust::Scanner;
304    ///
305    /// let mut sc = Scanner::new("123 456\r\n789 \n\n 中文 ".as_bytes());
306    ///
307    /// assert_eq!(Some("123 456".into()), sc.next_line().unwrap());
308    /// assert_eq!(Some("789 ".into()), sc.next_line().unwrap());
309    /// assert_eq!(Some("".into()), sc.next_line().unwrap());
310    /// assert_eq!(Some(" 中文 ".into()), sc.next_line().unwrap());
311    /// ```
312    pub fn next_line(&mut self) -> Result<Option<String>, ScannerError> {
313        if !self.passing_read()? {
314            return Ok(None);
315        }
316
317        let mut temp = String::new();
318
319        loop {
320            let e = self.buf[self.buf_offset];
321
322            let width = get_width(e);
323
324            match width {
325                0 => {
326                    self.buf_left_shift(1);
327
328                    temp.push(REPLACEMENT_CHARACTER);
329                },
330                1 => {
331                    if e == b'\n' || e == b'\r' {
332                        self.buf_skip_line(0);
333
334                        return Ok(Some(temp));
335                    }
336
337                    self.buf_left_shift(1);
338
339                    temp.push(e as char);
340                },
341                _ => {
342                    let width = self.buf_fill_char(width)?;
343
344                    self.buf_push_char(&mut temp, width);
345                },
346            }
347
348            if self.buf_length == 0 {
349                let size = read(&mut self.reader, &mut self.buf[self.buf_offset..])?;
350
351                if size == 0 {
352                    return Ok(Some(temp));
353                }
354
355                self.buf_length += size;
356            }
357        }
358    }
359
360    /// Read the next line but not include the trailing line character (or line characters like `CrLf`(`\r\n`)) without fully validating UTF-8. If there is nothing to read, it will return `Ok(None)`.
361    ///
362    /// ```rust
363    /// use scanner_rust::Scanner;
364    ///
365    /// let mut sc = Scanner::new("123 456\r\n789 \n\n 中文 ".as_bytes());
366    ///
367    /// assert_eq!(Some("123 456".into()), sc.next_line_raw().unwrap());
368    /// assert_eq!(Some("789 ".into()), sc.next_line_raw().unwrap());
369    /// assert_eq!(Some("".into()), sc.next_line_raw().unwrap());
370    /// assert_eq!(Some(" 中文 ".into()), sc.next_line_raw().unwrap());
371    /// ```
372    pub fn next_line_raw(&mut self) -> Result<Option<Vec<u8>>, ScannerError> {
373        if !self.passing_read()? {
374            return Ok(None);
375        }
376
377        let mut temp = Vec::new();
378
379        loop {
380            let data = &self.buf[self.buf_offset..(self.buf_offset + self.buf_length)];
381
382            if let Some(line_length) = data.iter().position(|&byte| byte == b'\n' || byte == b'\r')
383            {
384                temp.extend_from_slice(&data[..line_length]);
385                self.buf_skip_line(line_length);
386
387                return Ok(Some(temp));
388            }
389
390            temp.extend_from_slice(data);
391            self.buf_left_shift(self.buf_length);
392
393            if !self.passing_read()? {
394                return Ok(Some(temp));
395            }
396        }
397    }
398
399    /// Drop the next line but not include the trailing line character (or line characters like `CrLf`(`\r\n`)). If there is nothing to read, it will return `Ok(None)`. If there is something to read, it will return `Ok(Some(i))`. The `i` is the length (in bytes) of the dropped line.
400    ///
401    /// ```rust
402    /// use scanner_rust::Scanner;
403    ///
404    /// let mut sc = Scanner::new("123 456\r\n789 \n\n 中文 ".as_bytes());
405    ///
406    /// assert_eq!(Some(7), sc.drop_next_line().unwrap());
407    /// assert_eq!(Some("789 ".into()), sc.next_line().unwrap());
408    /// assert_eq!(Some(0), sc.drop_next_line().unwrap());
409    /// assert_eq!(Some(" 中文 ".into()), sc.next_line().unwrap());
410    /// assert_eq!(None, sc.drop_next_line().unwrap());
411    /// ```
412    pub fn drop_next_line(&mut self) -> Result<Option<usize>, ScannerError> {
413        if !self.passing_read()? {
414            return Ok(None);
415        }
416
417        let mut c = 0;
418
419        loop {
420            let data = &self.buf[self.buf_offset..(self.buf_offset + self.buf_length)];
421
422            if let Some(line_length) = data.iter().position(|&byte| byte == b'\n' || byte == b'\r')
423            {
424                self.buf_skip_line(line_length);
425
426                return Ok(Some(c + line_length));
427            }
428
429            c += self.buf_length;
430            self.buf_left_shift(self.buf_length);
431
432            if !self.passing_read()? {
433                return Ok(Some(c));
434            }
435        }
436    }
437}
438
439impl<R: Read, const N: usize> Scanner<R, N> {
440    /// Skip the next whitespaces (`javaWhitespace`). If there is nothing to read, it will return `Ok(false)`.
441    ///
442    /// ```rust
443    /// use scanner_rust::Scanner;
444    ///
445    /// let mut sc = Scanner::new("1 2   c".as_bytes());
446    ///
447    /// assert_eq!(Some('1'), sc.next_char().unwrap());
448    /// assert_eq!(Some(' '), sc.next_char().unwrap());
449    /// assert_eq!(Some('2'), sc.next_char().unwrap());
450    /// assert_eq!(true, sc.skip_whitespaces().unwrap());
451    /// assert_eq!(Some('c'), sc.next_char().unwrap());
452    /// assert_eq!(false, sc.skip_whitespaces().unwrap());
453    /// ```
454    pub fn skip_whitespaces(&mut self) -> Result<bool, ScannerError> {
455        if !self.passing_read()? {
456            return Ok(false);
457        }
458
459        loop {
460            let e = self.buf[self.buf_offset];
461
462            let width = get_width(e);
463
464            match width {
465                0 => {
466                    break;
467                },
468                1 => {
469                    if !is_whitespace_1(e) {
470                        break;
471                    }
472
473                    self.buf_left_shift(1);
474                },
475                3 if self.buf_fill_char(width)? == width
476                    && is_whitespace_3(
477                        self.buf[self.buf_offset],
478                        self.buf[self.buf_offset + 1],
479                        self.buf[self.buf_offset + 2],
480                    ) =>
481                {
482                    self.buf_left_shift(3);
483                },
484                _ => {
485                    break;
486                },
487            }
488
489            if self.buf_length == 0 {
490                let size = read(&mut self.reader, &mut self.buf[self.buf_offset..])?;
491
492                if size == 0 {
493                    return Ok(true);
494                }
495
496                self.buf_length += size;
497            }
498        }
499
500        Ok(true)
501    }
502
503    /// Read the next token separated by whitespaces. If there is nothing to read, it will return `Ok(None)`.
504    ///
505    /// ```rust
506    /// use scanner_rust::Scanner;
507    ///
508    /// let mut sc = Scanner::new("123 456\r\n789 \n\n 中文 ".as_bytes());
509    ///
510    /// assert_eq!(Some("123".into()), sc.next().unwrap());
511    /// assert_eq!(Some("456".into()), sc.next().unwrap());
512    /// assert_eq!(Some("789".into()), sc.next().unwrap());
513    /// assert_eq!(Some("中文".into()), sc.next().unwrap());
514    /// assert_eq!(None, sc.next().unwrap());
515    /// ```
516    #[allow(clippy::should_implement_trait)]
517    pub fn next(&mut self) -> Result<Option<String>, ScannerError> {
518        if !self.skip_whitespaces()? || self.buf_length == 0 {
519            return Ok(None);
520        }
521
522        let mut temp = String::new();
523
524        loop {
525            let e = self.buf[self.buf_offset];
526
527            let width = get_width(e);
528
529            match width {
530                0 => {
531                    self.buf_left_shift(1);
532
533                    temp.push(REPLACEMENT_CHARACTER);
534                },
535                1 => {
536                    if is_whitespace_1(e) {
537                        return Ok(Some(temp));
538                    }
539
540                    self.buf_left_shift(1);
541
542                    temp.push(e as char);
543                },
544                _ => {
545                    let width = self.buf_fill_char(width)?;
546
547                    if width == 3
548                        && is_whitespace_3(
549                            self.buf[self.buf_offset],
550                            self.buf[self.buf_offset + 1],
551                            self.buf[self.buf_offset + 2],
552                        )
553                    {
554                        return Ok(Some(temp));
555                    }
556
557                    self.buf_push_char(&mut temp, width);
558                },
559            }
560
561            if self.buf_length == 0 {
562                let size = read(&mut self.reader, &mut self.buf[self.buf_offset..])?;
563
564                if size == 0 {
565                    return Ok(Some(temp));
566                }
567
568                self.buf_length += size;
569            }
570        }
571    }
572
573    /// Read the next token separated by whitespaces without fully validating UTF-8. If there is nothing to read, it will return `Ok(None)`.
574    ///
575    /// ```rust
576    /// use scanner_rust::Scanner;
577    ///
578    /// let mut sc = Scanner::new("123 456\r\n789 \n\n 中文 ".as_bytes());
579    ///
580    /// assert_eq!(Some("123".into()), sc.next_raw().unwrap());
581    /// assert_eq!(Some("456".into()), sc.next_raw().unwrap());
582    /// assert_eq!(Some("789".into()), sc.next_raw().unwrap());
583    /// assert_eq!(Some("中文".into()), sc.next_raw().unwrap());
584    /// assert_eq!(None, sc.next_raw().unwrap());
585    /// ```
586    pub fn next_raw(&mut self) -> Result<Option<Vec<u8>>, ScannerError> {
587        if !self.skip_whitespaces()? || self.buf_length == 0 {
588            return Ok(None);
589        }
590
591        let mut temp = Vec::new();
592
593        loop {
594            let width = self.buf_raw_char_width()?;
595
596            if (width == 1 && is_whitespace_1(self.buf[self.buf_offset]))
597                || (width == 3
598                    && is_whitespace_3(
599                        self.buf[self.buf_offset],
600                        self.buf[self.buf_offset + 1],
601                        self.buf[self.buf_offset + 2],
602                    ))
603            {
604                return Ok(Some(temp));
605            }
606
607            temp.extend_from_slice(&self.buf[self.buf_offset..(self.buf_offset + width)]);
608            self.buf_left_shift(width);
609
610            if !self.passing_read()? {
611                return Ok(Some(temp));
612            }
613        }
614    }
615
616    /// Drop the next token separated by whitespaces. If there is nothing to read, it will return `Ok(None)`. If there is something to read, it will return `Ok(Some(i))`. The `i` is the length (in bytes) of the dropped token.
617    ///
618    /// ```rust
619    /// use scanner_rust::Scanner;
620    ///
621    /// let mut sc = Scanner::new("123 456\r\n789 \n\n 中文 ".as_bytes());
622    ///
623    /// assert_eq!(Some(3), sc.drop_next().unwrap());
624    /// assert_eq!(Some("456".into()), sc.next().unwrap());
625    /// assert_eq!(Some(3), sc.drop_next().unwrap());
626    /// assert_eq!(Some("中文".into()), sc.next().unwrap());
627    /// assert_eq!(None, sc.drop_next().unwrap());
628    /// ```
629    pub fn drop_next(&mut self) -> Result<Option<usize>, ScannerError> {
630        if !self.skip_whitespaces()? || self.buf_length == 0 {
631            return Ok(None);
632        }
633
634        let mut c = 0;
635
636        loop {
637            let width = self.buf_raw_char_width()?;
638
639            if (width == 1 && is_whitespace_1(self.buf[self.buf_offset]))
640                || (width == 3
641                    && is_whitespace_3(
642                        self.buf[self.buf_offset],
643                        self.buf[self.buf_offset + 1],
644                        self.buf[self.buf_offset + 2],
645                    ))
646            {
647                return Ok(Some(c));
648            }
649
650            c += width;
651            self.buf_left_shift(width);
652
653            if !self.passing_read()? {
654                return Ok(Some(c));
655            }
656        }
657    }
658}
659
660impl<R: Read, const N: usize> Scanner<R, N> {
661    /// Read the next bytes. If there is nothing to read, it will return `Ok(None)`.
662    ///
663    /// ```rust
664    /// use scanner_rust::Scanner;
665    ///
666    /// let mut sc = Scanner::new("123 456\r\n789 \n\n 中文 ".as_bytes());
667    ///
668    /// assert_eq!(Some("123".into()), sc.next_bytes(3).unwrap());
669    /// assert_eq!(Some(" 456".into()), sc.next_bytes(4).unwrap());
670    /// assert_eq!(Some("\r\n789 ".into()), sc.next_bytes(6).unwrap());
671    /// assert_eq!(Some("中文".into()), sc.next_raw().unwrap());
672    /// assert_eq!(Some(" ".into()), sc.next_bytes(2).unwrap());
673    /// assert_eq!(None, sc.next_bytes(2).unwrap());
674    /// ```
675    pub fn next_bytes(
676        &mut self,
677        max_number_of_bytes: usize,
678    ) -> Result<Option<Vec<u8>>, ScannerError> {
679        if !self.passing_read()? {
680            return Ok(None);
681        }
682
683        let mut temp = Vec::new();
684        let mut c = 0;
685
686        while c < max_number_of_bytes {
687            if self.buf_length == 0 {
688                let size = read(&mut self.reader, &mut self.buf[self.buf_offset..])?;
689
690                if size == 0 {
691                    return Ok(Some(temp));
692                }
693
694                self.buf_length += size;
695            }
696
697            let dropping_bytes = self.buf_length.min(max_number_of_bytes - c);
698
699            temp.extend_from_slice(&self.buf[self.buf_offset..(self.buf_offset + dropping_bytes)]);
700
701            self.buf_left_shift(dropping_bytes);
702
703            c += dropping_bytes;
704        }
705
706        Ok(Some(temp))
707    }
708
709    /// Drop the next N bytes. If there is nothing to read, it will return `Ok(None)`. If there is something to read, it will return `Ok(Some(i))`. The `i` is the length of the actually dropped bytes.
710    ///
711    /// ```rust
712    /// use scanner_rust::Scanner;
713    ///
714    /// let mut sc = Scanner::new("123 456\r\n789 \n\n 中文 ".as_bytes());
715    ///
716    /// assert_eq!(Some(7), sc.drop_next_bytes(7).unwrap());
717    /// assert_eq!(Some("".into()), sc.next_line().unwrap());
718    /// assert_eq!(Some("789 ".into()), sc.next_line().unwrap());
719    /// assert_eq!(Some(1), sc.drop_next_bytes(1).unwrap());
720    /// assert_eq!(Some(" 中文 ".into()), sc.next_line().unwrap());
721    /// assert_eq!(None, sc.drop_next_bytes(1).unwrap());
722    /// ```
723    pub fn drop_next_bytes(
724        &mut self,
725        max_number_of_bytes: usize,
726    ) -> Result<Option<usize>, ScannerError> {
727        if !self.passing_read()? {
728            return Ok(None);
729        }
730
731        let mut c = 0;
732
733        while c < max_number_of_bytes {
734            if self.buf_length == 0 {
735                let size = read(&mut self.reader, &mut self.buf[self.buf_offset..])?;
736
737                if size == 0 {
738                    return Ok(Some(c));
739                }
740
741                self.buf_length += size;
742            }
743
744            let dropping_bytes = self.buf_length.min(max_number_of_bytes - c);
745
746            self.buf_left_shift(dropping_bytes);
747
748            c += dropping_bytes;
749        }
750
751        Ok(Some(c))
752    }
753}
754
755impl<R: Read, const N: usize> Scanner<R, N> {
756    /// Read the next text until it reaches a specific boundary. If there is nothing to read, it will return `Ok(None)`.
757    ///
758    /// An empty boundary reads all remaining data.
759    ///
760    /// ```rust
761    /// use scanner_rust::Scanner;
762    ///
763    /// let mut sc = Scanner::new("123 456\r\n789 \n\n 中文 ".as_bytes());
764    ///
765    /// assert_eq!(Some("123".into()), sc.next_until(" ").unwrap());
766    /// assert_eq!(Some("456\r".into()), sc.next_until("\n").unwrap());
767    /// assert_eq!(Some("78".into()), sc.next_until("9 ").unwrap());
768    /// assert_eq!(Some("\n\n 中文 ".into()), sc.next_until("kk").unwrap());
769    /// assert_eq!(None, sc.next().unwrap());
770    /// ```
771    pub fn next_until<S: AsRef<str>>(
772        &mut self,
773        boundary: S,
774    ) -> Result<Option<String>, ScannerError> {
775        let boundary = boundary.as_ref();
776
777        Ok(self.next_until_raw(boundary.as_bytes())?.map(into_string_lossy))
778    }
779
780    /// Read the next data until it reaches a specific boundary without fully validating UTF-8. If there is nothing to read, it will return `Ok(None)`.
781    ///
782    /// An empty boundary reads all remaining data.
783    ///
784    /// ```rust
785    /// use scanner_rust::Scanner;
786    ///
787    /// let mut sc = Scanner::new("123 456\r\n789 \n\n 中文 ".as_bytes());
788    ///
789    /// assert_eq!(Some("123".into()), sc.next_until_raw(" ").unwrap());
790    /// assert_eq!(Some("456\r".into()), sc.next_until_raw("\n").unwrap());
791    /// assert_eq!(Some("78".into()), sc.next_until_raw("9 ").unwrap());
792    /// assert_eq!(Some("\n\n 中文 ".into()), sc.next_until_raw("kk").unwrap());
793    /// assert_eq!(None, sc.next().unwrap());
794    /// ```
795    pub fn next_until_raw<D: ?Sized + AsRef<[u8]>>(
796        &mut self,
797        boundary: &D,
798    ) -> Result<Option<Vec<u8>>, ScannerError> {
799        if !self.passing_read()? {
800            return Ok(None);
801        }
802
803        let boundary = boundary.as_ref();
804        let boundary_length = boundary.len();
805        let mut temp = Vec::new();
806
807        // An empty boundary never matches, so keep reading until the end.
808        if boundary_length == 0 {
809            loop {
810                temp.extend_from_slice(
811                    &self.buf[self.buf_offset..(self.buf_offset + self.buf_length)],
812                );
813
814                self.buf_left_shift(self.buf_length);
815
816                let size = read(&mut self.reader, &mut self.buf[self.buf_offset..])?;
817
818                if size == 0 {
819                    return Ok(Some(temp));
820                }
821
822                self.buf_length += size;
823            }
824        }
825
826        // Match the boundary across buffer refills with KMP so a mismatch never re-reads bytes.
827        let lps = compute_lps(boundary);
828        let mut b = 0;
829
830        loop {
831            let mut i = 0;
832
833            while i < self.buf_length {
834                let e = self.buf[self.buf_offset + i];
835
836                while b > 0 && e != boundary[b] {
837                    b = lps[b - 1];
838                }
839
840                if e == boundary[b] {
841                    b += 1;
842                }
843
844                i += 1;
845
846                if b == boundary_length {
847                    // The matched boundary is the last `boundary_length` bytes seen so far.
848                    temp.extend_from_slice(&self.buf[self.buf_offset..(self.buf_offset + i)]);
849                    temp.truncate(temp.len() - boundary_length);
850
851                    self.buf_left_shift(i);
852
853                    return Ok(Some(temp));
854                }
855            }
856
857            temp.extend_from_slice(&self.buf[self.buf_offset..(self.buf_offset + self.buf_length)]);
858
859            self.buf_left_shift(self.buf_length);
860
861            let size = read(&mut self.reader, &mut self.buf[self.buf_offset..])?;
862
863            if size == 0 {
864                return Ok(Some(temp));
865            }
866
867            self.buf_length += size;
868        }
869    }
870
871    /// Drop the next data until it reaches a specific boundary. If there is nothing to read, it will return `Ok(None)`. If there is something to read, it will return `Ok(Some(i))`. The `i` is the length (in bytes) of the dropped data, excluding the boundary.
872    ///
873    /// An empty boundary drops all remaining data.
874    ///
875    /// ```rust
876    /// use scanner_rust::Scanner;
877    ///
878    /// let mut sc = Scanner::new("123 456\r\n789 \n\n 中文 ".as_bytes());
879    ///
880    /// assert_eq!(Some(7), sc.drop_next_until("\r\n").unwrap());
881    /// assert_eq!(Some("789 ".into()), sc.next_line().unwrap());
882    /// assert_eq!(Some(0), sc.drop_next_until("\n").unwrap());
883    /// assert_eq!(Some(" 中文 ".into()), sc.next_line().unwrap());
884    /// assert_eq!(None, sc.drop_next_until("").unwrap());
885    /// ```
886    pub fn drop_next_until<D: ?Sized + AsRef<[u8]>>(
887        &mut self,
888        boundary: &D,
889    ) -> Result<Option<usize>, ScannerError> {
890        if !self.passing_read()? {
891            return Ok(None);
892        }
893
894        let boundary = boundary.as_ref();
895        let boundary_length = boundary.len();
896        let mut c = 0;
897
898        // An empty boundary never matches, so keep reading until the end.
899        if boundary_length == 0 {
900            loop {
901                c += self.buf_length;
902
903                self.buf_left_shift(self.buf_length);
904
905                let size = read(&mut self.reader, &mut self.buf[self.buf_offset..])?;
906
907                if size == 0 {
908                    return Ok(Some(c));
909                }
910
911                self.buf_length += size;
912            }
913        }
914
915        // Match the boundary across buffer refills with KMP so a mismatch never re-reads bytes.
916        let lps = compute_lps(boundary);
917        let mut b = 0;
918
919        loop {
920            let mut i = 0;
921
922            while i < self.buf_length {
923                let e = self.buf[self.buf_offset + i];
924
925                while b > 0 && e != boundary[b] {
926                    b = lps[b - 1];
927                }
928
929                if e == boundary[b] {
930                    b += 1;
931                }
932
933                i += 1;
934
935                if b == boundary_length {
936                    self.buf_left_shift(i);
937
938                    return Ok(Some(c + i - boundary_length));
939                }
940            }
941
942            c += self.buf_length;
943
944            self.buf_left_shift(self.buf_length);
945
946            let size = read(&mut self.reader, &mut self.buf[self.buf_offset..])?;
947
948            if size == 0 {
949                return Ok(Some(c));
950            }
951
952            self.buf_length += size;
953        }
954    }
955}
956
957impl<R: Read, const N: usize> Scanner<R, N> {
958    /// Fill up the buffer as much as possible and return an immutable slice of all the currently buffered (unread) data.
959    /// Reading stops at the end of the stream or when the buffer is full. If `shift` is `true`, the buffered data is first moved to the front of the buffer so that up to the whole buffer size can be filled; if `false`, only the space after the current read position is filled.
960    ///
961    /// ```rust
962    /// use scanner_rust::Scanner;
963    ///
964    /// let mut sc = Scanner::new("123 456\r\n789 \n\n 中文 ".as_bytes());
965    ///
966    /// assert_eq!("123 456\r\n789 \n\n 中文 ".as_bytes(), sc.peek(false).unwrap());
967    /// ```
968    #[inline]
969    pub fn peek(&mut self, shift: bool) -> Result<&[u8], ScannerError> {
970        // Consume any line-terminator byte deferred by a previous read so it is not peeked again.
971        if !self.passing_read()? {
972            return Ok(&[]);
973        }
974
975        if shift {
976            self.buf_align_to_front_end();
977        }
978
979        while self.buf_offset + self.buf_length < N {
980            let size =
981                read(&mut self.reader, &mut self.buf[(self.buf_offset + self.buf_length)..])?;
982
983            if size == 0 {
984                break;
985            }
986
987            self.buf_length += size;
988        }
989
990        Ok(&self.buf[self.buf_offset..(self.buf_offset + self.buf_length)])
991    }
992}
993
994impl<R: Read, const N: usize> Scanner<R, N> {
995    #[inline]
996    fn next_raw_parse<T: FromStr>(&mut self) -> Result<Option<T>, ScannerError>
997    where
998        ScannerError: From<<T as FromStr>::Err>, {
999        let result = self.next_raw()?;
1000
1001        match result {
1002            Some(s) => Ok(Some(numeric_text(&s).parse()?)),
1003            None => Ok(None),
1004        }
1005    }
1006}
1007
1008impl<R: Read, const N: usize> Scanner<R, N> {
1009    #[inline]
1010    fn next_until_raw_parse<T: FromStr, D: ?Sized + AsRef<[u8]>>(
1011        &mut self,
1012        boundary: &D,
1013    ) -> Result<Option<T>, ScannerError>
1014    where
1015        ScannerError: From<<T as FromStr>::Err>, {
1016        let result = self.next_until_raw(boundary)?;
1017
1018        match result {
1019            Some(s) => Ok(Some(numeric_text(&s).parse()?)),
1020            None => Ok(None),
1021        }
1022    }
1023}
1024
1025macro_rules! scanner_number_methods {
1026    ($(($t:ty, $next:ident, $next_until:ident, $sample:literal, $v1:literal, $v2:literal)),+ $(,)?) => {
1027        impl<R: Read, const N: usize> Scanner<R, N> {
1028            $(
1029                #[doc = concat!(
1030                    "Read the next token separated by whitespaces and parse it to a `", stringify!($t), "` value. If there is nothing to read, it will return `Ok(None)`.\n\n```rust\nuse scanner_rust::Scanner;\n\nlet mut sc = Scanner::new(", stringify!($sample), ".as_bytes());\n\nassert_eq!(Some(", stringify!($v1), "), sc.", stringify!($next), "().unwrap());\nassert_eq!(Some(", stringify!($v2), "), sc.", stringify!($next), "().unwrap());\n```"
1031                )]
1032                #[inline]
1033                pub fn $next(&mut self) -> Result<Option<$t>, ScannerError> {
1034                    self.next_raw_parse()
1035                }
1036            )+
1037        }
1038
1039        impl<R: Read, const N: usize> Scanner<R, N> {
1040            $(
1041                #[doc = concat!(
1042                    "Read the next text until it reaches a specific boundary and parse it to a `", stringify!($t), "` value. If there is nothing to read, it will return `Ok(None)`. An empty boundary reads all remaining data before parsing.\n\n```rust\nuse scanner_rust::Scanner;\n\nlet mut sc = Scanner::new(", stringify!($sample), ".as_bytes());\n\nassert_eq!(Some(", stringify!($v1), "), sc.", stringify!($next_until), "(\" \").unwrap());\nassert_eq!(Some(", stringify!($v2), "), sc.", stringify!($next_until), "(\" \").unwrap());\n```"
1043                )]
1044                #[inline]
1045                pub fn $next_until<D: ?Sized + AsRef<[u8]>>(
1046                    &mut self,
1047                    boundary: &D,
1048                ) -> Result<Option<$t>, ScannerError> {
1049                    self.next_until_raw_parse(boundary)
1050                }
1051            )+
1052        }
1053    };
1054}
1055
1056scanner_number_methods! {
1057    (u8, next_u8, next_u8_until, "1 2", 1, 2),
1058    (u16, next_u16, next_u16_until, "1 2", 1, 2),
1059    (u32, next_u32, next_u32_until, "1 2", 1, 2),
1060    (u64, next_u64, next_u64_until, "1 2", 1, 2),
1061    (u128, next_u128, next_u128_until, "1 2", 1, 2),
1062    (usize, next_usize, next_usize_until, "1 2", 1, 2),
1063    (i8, next_i8, next_i8_until, "1 2", 1, 2),
1064    (i16, next_i16, next_i16_until, "1 2", 1, 2),
1065    (i32, next_i32, next_i32_until, "1 2", 1, 2),
1066    (i64, next_i64, next_i64_until, "1 2", 1, 2),
1067    (i128, next_i128, next_i128_until, "1 2", 1, 2),
1068    (isize, next_isize, next_isize_until, "1 2", 1, 2),
1069    (f32, next_f32, next_f32_until, "1 2.5", 1.0, 2.5),
1070    (f64, next_f64, next_f64_until, "1 2.5", 1.0, 2.5),
1071}