noa_parser/
scanner.rs

1//! A scanner for a sequence of elements.
2
3use crate::errors::ParseResult;
4use crate::visitor::Visitor;
5use std::io::Cursor;
6use std::ops::Deref;
7
8/// Wrapper around a `Cursor`.
9#[derive(Debug, PartialEq)]
10pub struct Scanner<'a, T> {
11    /// The internal cursor.
12    cursor: Cursor<&'a [T]>,
13}
14
15impl<'a, T> Scanner<'a, T> {
16    pub fn new(data: &'a [T]) -> Scanner<'a, T> {
17        Scanner {
18            cursor: Cursor::new(data),
19        }
20    }
21}
22
23impl<'a, T> Scanner<'a, T> {
24    /// Move the internal cursor forward by `n` positions.
25    ///
26    /// # Arguments
27    ///
28    /// * `n` - The number of positions to move the cursor forward.
29    ///
30    /// # Panics
31    ///
32    /// Panics if the internal cursor is moved past the end of the data.
33    pub fn bump_by(&mut self, n: usize) {
34        self.cursor.set_position(self.cursor.position() + n as u64);
35    }
36
37    /// Move the internal cursor to the specified position.
38    ///
39    /// # Arguments
40    ///
41    /// * `n` - The position to move the cursor to.
42    ///
43    /// # Panics
44    ///
45    /// Panics if the internal cursor is moved past the end of the data.
46    pub fn jump_to(&mut self, n: usize) {
47        self.cursor.set_position(n as u64);
48    }
49
50    /// Move the internal cursor backward by `n` positions.
51    ///
52    /// # Arguments
53    ///
54    /// * `n` - The number of positions to move the cursor backward.
55    ///
56    /// # Panics
57    ///
58    /// Panics if the internal cursor is moved to a position before the start of the data.
59    pub fn rewind(&mut self, n: usize) {
60        self.cursor.set_position(self.cursor.position() - n as u64);
61    }
62
63    /// Return the current position of the internal cursor.
64    ///
65    /// # Returns
66    ///
67    /// The current position of the internal cursor.
68    pub fn current_position(&self) -> usize {
69        self.cursor.position() as usize
70    }
71
72    /// Return a slice of the data that remains to be scanned.
73    ///
74    /// # Returns
75    ///
76    /// A slice of the data that remains to be scanned.
77    pub fn remaining(&self) -> &[T] {
78        &self.cursor.get_ref()[self.current_position()..]
79    }
80
81    /// Return the original data given to the scanner.
82    ///
83    /// # Returns
84    ///
85    /// The original data given to the scanner.
86    pub fn data(&self) -> &'a [T] {
87        self.cursor.get_ref()
88    }
89
90    /// Consume the scanner and return a slice of the remaining data.
91    ///
92    /// # Returns
93    ///
94    /// A slice of the remaining data.
95    pub fn into_data(self) -> &'a [T] {
96        &self.cursor.get_ref()[self.current_position()..]
97    }
98
99    /// Return true if there are no more elements to scan, false otherwise.
100    ///
101    /// # Returns
102    ///
103    /// true if there are no more elements to scan, false otherwise.
104    pub fn is_empty(&self) -> bool {
105        self.remaining().is_empty()
106    }
107}
108
109impl<'a, T> Deref for Scanner<'a, T> {
110    type Target = [T];
111    fn deref(&self) -> &Self::Target {
112        self.remaining()
113    }
114}
115
116impl<'a, T> Scanner<'a, T> {
117    /// Run a visitor on the scanner.
118    ///
119    /// # Type Parameters
120    ///
121    /// * `V` - The type of the visitor to run.
122    ///
123    /// # Arguments
124    ///
125    /// * `&mut self` - The scanner to run the visitor on.
126    ///
127    /// # Returns
128    ///
129    /// The result of running the visitor on the scanner.
130    pub fn visit<V: Visitor<'a, T>>(&mut self) -> ParseResult<V> {
131        V::accept(self)
132    }
133}