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}