noa_parser/
scanner.rs

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