mirror of
				https://github.com/rust-lang/rust.git
				synced 2025-10-31 04:57:19 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			85 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			85 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| use std::str::Chars;
 | |
| 
 | |
| /// Peekable iterator over a char sequence.
 | |
| ///
 | |
| /// Next characters can be peeked via `nth_char` method,
 | |
| /// and position can be shifted forward via `bump` method.
 | |
| pub(crate) struct Cursor<'a> {
 | |
|     initial_len: usize,
 | |
|     chars: Chars<'a>,
 | |
|     #[cfg(debug_assertions)]
 | |
|     prev: char,
 | |
| }
 | |
| 
 | |
| pub(crate) const EOF_CHAR: char = '\0';
 | |
| 
 | |
| impl<'a> Cursor<'a> {
 | |
|     pub(crate) fn new(input: &'a str) -> Cursor<'a> {
 | |
|         Cursor {
 | |
|             initial_len: input.len(),
 | |
|             chars: input.chars(),
 | |
|             #[cfg(debug_assertions)]
 | |
|             prev: EOF_CHAR,
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /// Returns the last eaten symbol (or `'\0'` in release builds).
 | |
|     /// (For debug assertions only.)
 | |
|     pub(crate) fn prev(&self) -> char {
 | |
|         #[cfg(debug_assertions)]
 | |
|         {
 | |
|             self.prev
 | |
|         }
 | |
| 
 | |
|         #[cfg(not(debug_assertions))]
 | |
|         {
 | |
|             EOF_CHAR
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /// Returns nth character relative to the current cursor position.
 | |
|     /// If requested position doesn't exist, `EOF_CHAR` is returned.
 | |
|     /// However, getting `EOF_CHAR` doesn't always mean actual end of file,
 | |
|     /// it should be checked with `is_eof` method.
 | |
|     fn nth_char(&self, n: usize) -> char {
 | |
|         self.chars().nth(n).unwrap_or(EOF_CHAR)
 | |
|     }
 | |
| 
 | |
|     /// Peeks the next symbol from the input stream without consuming it.
 | |
|     pub(crate) fn first(&self) -> char {
 | |
|         self.nth_char(0)
 | |
|     }
 | |
| 
 | |
|     /// Peeks the second symbol from the input stream without consuming it.
 | |
|     pub(crate) fn second(&self) -> char {
 | |
|         self.nth_char(1)
 | |
|     }
 | |
| 
 | |
|     /// Checks if there is nothing more to consume.
 | |
|     pub(crate) fn is_eof(&self) -> bool {
 | |
|         self.chars.as_str().is_empty()
 | |
|     }
 | |
| 
 | |
|     /// Returns amount of already consumed symbols.
 | |
|     pub(crate) fn len_consumed(&self) -> usize {
 | |
|         self.initial_len - self.chars.as_str().len()
 | |
|     }
 | |
| 
 | |
|     /// Returns a `Chars` iterator over the remaining characters.
 | |
|     fn chars(&self) -> Chars<'a> {
 | |
|         self.chars.clone()
 | |
|     }
 | |
| 
 | |
|     /// Moves to the next character.
 | |
|     pub(crate) fn bump(&mut self) -> Option<char> {
 | |
|         let c = self.chars.next()?;
 | |
| 
 | |
|         #[cfg(debug_assertions)]
 | |
|         {
 | |
|             self.prev = c;
 | |
|         }
 | |
| 
 | |
|         Some(c)
 | |
|     }
 | |
| }
 | 
