1 // Copyright (c) 2023 Huawei Device Co., Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 mod io_reader; 15 pub(crate) use io_reader::IoReader; 16 17 mod slice_reader; 18 pub(crate) use slice_reader::SliceReader; 19 20 /// `BytesReader` provides the basic byte read interface, such as `next`, 21 /// `peek`, `index`. Users can obtain the next byte or the current read 22 /// position according to these interfaces. 23 pub(crate) trait BytesReader { 24 /// Errors that may occur during reading, usually in the I\O process. 25 type Error: Into<Box<dyn std::error::Error>>; 26 27 /// Get the next character and move the cursor to the next place. next(&mut self) -> Result<Option<u8>, Self::Error>28 fn next(&mut self) -> Result<Option<u8>, Self::Error>; 29 30 /// Get the next character, but don't move the cursor. So the next read 31 /// will get the same character. peek(&mut self) -> Result<Option<u8>, Self::Error>32 fn peek(&mut self) -> Result<Option<u8>, Self::Error>; 33 34 /// Discard the next character and move the cursor to the next place. discard(&mut self)35 fn discard(&mut self); 36 37 /// Get the current cursor position and return it as usize. index(&self) -> usize38 fn index(&self) -> usize; 39 40 /// Get the current cursor position and return it as `Position`. position(&self) -> Position41 fn position(&self) -> Position; 42 } 43 44 /// `Cacheable` provides some byte cache interfaces for caching a portion of 45 /// contiguous bytes in a byte stream. 46 pub(crate) trait Cacheable: BytesReader { 47 /// Start the cache operation. This interface needs to be used with 48 /// `end_caching` or `take_cached_data`. start_caching(&mut self)49 fn start_caching(&mut self); 50 51 /// Get the length of the cached bytes. Since the logic of caching 52 /// operations is implementation-dependent, we provide an interface that 53 /// uses mutable references here. cached_len(&mut self) -> Option<usize>54 fn cached_len(&mut self) -> Option<usize>; 55 56 /// Get a slice of the cached bytes. Since the logic of caching operations 57 /// is implementation-dependent, we provide an interface that uses mutable 58 /// references here. cached_slice(&mut self) -> Option<&[u8]>59 fn cached_slice(&mut self) -> Option<&[u8]>; 60 61 /// Get a `Vec` of the cached bytes. Since the logic of caching operations 62 /// is implementation-dependent, we provide an interface that uses mutable 63 /// references here. cached_data(&mut self) -> Option<Vec<u8>>64 fn cached_data(&mut self) -> Option<Vec<u8>>; 65 66 /// End the cache operation. This interface needs to be used with 67 /// `start_caching`. end_caching(&mut self)68 fn end_caching(&mut self); 69 70 /// End the cache operation and return the cached bytes. This interface 71 /// needs to be used with `start_caching`. take_cached_data(&mut self) -> Option<Vec<u8>>72 fn take_cached_data(&mut self) -> Option<Vec<u8>>; 73 } 74 75 /// `RemainderCountable` provides the interface related to the remainder. 76 pub(crate) trait RemainderCountable: BytesReader { 77 /// Get the length of the remainder. remainder_len(&self) -> usize78 fn remainder_len(&self) -> usize; 79 80 /// Get a slice of the remainder. remainder_slice(&self) -> &[u8]81 fn remainder_slice(&self) -> &[u8]; 82 83 /// Get a `Vec<u8>` of the remainder. remainder_data(&self) -> Vec<u8>84 fn remainder_data(&self) -> Vec<u8>; 85 } 86 87 /// `NBytesReadable` provides interfaces to read 'n' bytes at one time. 88 pub(crate) trait NBytesReadable: BytesReader { 89 /// Read the next 'n' bytes and move the cursor to the next nth position. 90 /// If there are not enough bytes remaining to satisfy 'n', return `None` 91 /// and do nothing. next_n(&mut self, n: usize) -> Result<Option<&[u8]>, Self::Error>92 fn next_n(&mut self, n: usize) -> Result<Option<&[u8]>, Self::Error>; 93 94 /// Get the next 'n' bytes and do not move the cursor. If there are not 95 /// enough bytes remaining to satisfy 'n', return `None` and do nothing. peek_n(&mut self, n: usize) -> Result<Option<&[u8]>, Self::Error>96 fn peek_n(&mut self, n: usize) -> Result<Option<&[u8]>, Self::Error>; 97 98 /// Discard the next 'n' bytes and move the cursor to the next nth position. 99 /// If there are not enough bytes remaining to satisfy 'n', do nothing. discard_n(&mut self, n: usize)100 fn discard_n(&mut self, n: usize); 101 } 102 103 /// Position information which expressed in row and column. 104 #[derive(Clone)] 105 pub(crate) struct Position { 106 line: usize, 107 column: usize, 108 } 109 110 impl Position { 111 /// Create a `Position` from the given line and column. 112 #[inline] new(line: usize, column: usize) -> Self113 pub(crate) fn new(line: usize, column: usize) -> Self { 114 Self { line, column } 115 } 116 117 /// Get line. 118 #[inline] line(&self) -> usize119 pub(crate) fn line(&self) -> usize { 120 self.line 121 } 122 123 /// Get column. 124 #[inline] column(&self) -> usize125 pub(crate) fn column(&self) -> usize { 126 self.column 127 } 128 } 129 130 #[cfg(test)] 131 mod ut_position { 132 use super::Position; 133 134 /// UT test for `Position::new`. 135 /// 136 /// # Title 137 /// ut_position_new 138 /// 139 /// # Brief 140 /// 1. Call `Position::new` to create a `Position`. 141 /// 2. Check if the results are correct. 142 #[test] ut_position_new()143 fn ut_position_new() { 144 let position = Position::new(1, 1); 145 assert_eq!(position.line, 1); 146 assert_eq!(position.column, 1); 147 } 148 149 /// UT test for `Position::line`. 150 /// 151 /// # Title 152 /// ut_position_line 153 /// 154 /// # Brief 155 /// 1. Create a `Position`. 156 /// 2. Call `Position::line` to get the line number of `Position`. 157 /// 3. Check if the results are correct. 158 #[test] ut_position_line()159 fn ut_position_line() { 160 let position = Position::new(1, 1); 161 assert_eq!(position.line(), 1); 162 } 163 164 /// UT test for `Position::column`. 165 /// 166 /// # Title 167 /// ut_position_column 168 /// 169 /// # Brief 170 /// 1. Create a `Position`. 171 /// 2. Call `Position::column` to get the column number of `Position`. 172 /// 3. Check if the results are correct. 173 #[test] ut_position_column()174 fn ut_position_column() { 175 let position = Position::new(1, 1); 176 assert_eq!(position.column(), 1); 177 } 178 179 /// UT test case for `Position::clone`. 180 /// 181 /// # Title 182 /// ut_position_clone 183 /// 184 /// # Brief 185 /// 1. Create a `Position`. 186 /// 2. Call `Position::clone` to get a copy of `Position`. 187 /// 3. Check if the results are correct. 188 #[allow(clippy::redundant_clone)] 189 #[test] ut_position_clone()190 fn ut_position_clone() { 191 let position = Position::new(1, 1); 192 let position = position.clone(); 193 assert_eq!(position.line, 1); 194 assert_eq!(position.column, 1); 195 } 196 } 197