summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/scanner.rs41
1 files changed, 41 insertions, 0 deletions
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<char> {
+ 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.