From fe5bd437fd459bebef596340480159767e041223 Mon Sep 17 00:00:00 2001 From: Mica White Date: Wed, 4 Sep 2024 20:16:29 -0400 Subject: New scanner methods --- src/scanner.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'src') diff --git a/src/scanner.rs b/src/scanner.rs index 6c82041..a68199c 100644 --- a/src/scanner.rs +++ b/src/scanner.rs @@ -182,6 +182,47 @@ impl Scanner { self.goto(position) } + /// Increase the position by one, if possible. If the new position would be + /// outside of the range of the source, then `None` is returned. Otherwise, + /// the character that was passed over is returned. + /// + /// # Example + /// + /// ``` + /// use snob::Scanner; + /// + /// let mut scanner = Scanner::new("Hello, world"); + /// let c = scanner.advance_char(); + /// assert_eq!(scanner.position(), 1); + /// assert_eq!(c, 'H'); + /// ``` + pub fn advance_char(&mut self) -> Option { + let char = self.source.get(self.position)?; + self.position = self.position.checked_add(1)?; + Some(*char) + } + + /// Increases the position by the given `amount`, or advances to the end of + /// the source if the new position would be outside of the range of the + /// source. This returnes the subslice of the string from the old position + /// to the new position. + /// + /// ``` + /// use snob::Scanner; + /// + /// let mut scanner = Scanner::new("Hello, world!"); + /// let substr = scanner.advance_or_goto_end(20); + /// assert_eq!(scanner.position(), 13); + /// assert_eq!(substr, String::from("Hello, world!")) + /// ``` + pub fn advance_or_goto_end(&mut self, amount: isize) -> String { + let position = self + .position + .checked_add_signed(amount) + .unwrap_or(self.len()); + self.goto(position).expect("a valid position") + } + /// Looks for the given `substring` in the remainder of the scanner. If the /// substring is found, the position of the first character in the /// substring is returned. Otherwise, `None` is returned. -- cgit v1.2.3