don't use a null sentinel
diff --git a/rust/src/scanner.rs b/rust/src/scanner.rs
index 1b82962..879d7cb 100644
--- a/rust/src/scanner.rs
+++ b/rust/src/scanner.rs
@@ -76,7 +76,7 @@ impl<'a> Scanner<'a> {
}
fn is_at_end(&self) -> bool {
- self.source[self.current] == 0
+ self.current == self.source.len()
}
fn make_token(&self, kind: TokenKind) -> Result<Token> {
@@ -115,20 +115,19 @@ impl<'a> Scanner<'a> {
fn skip_whitespace(&mut self) {
loop {
- let c = self.peek();
- match c {
- ' ' | '\r' | '\t' => {
+ match self.peek() {
+ Some(' ') | Some('\r') | Some('\t') => {
self.advance();
break;
}
- '\n' => {
+ Some('\n') => {
self.line += 1;
self.advance();
break;
}
- '/' => {
- if self.peek_next() == '/' {
- while self.peek() != '\n' && !self.is_at_end() {
+ Some('/') => {
+ if matches!(self.peek_next(), Some(c) if c == '/') {
+ while matches!(self.peek(), Some(c) if c != '\n') {
self.advance();
}
} else {
@@ -142,21 +141,21 @@ impl<'a> Scanner<'a> {
}
}
- fn peek(&self) -> char {
- self.source[self.current] as char
+ fn peek(&self) -> Option<char> {
+ self.source.get(self.current).map(|&x| x as char)
}
- fn peek_next(&mut self) -> char {
+ fn peek_next(&mut self) -> Option<char> {
if self.is_at_end() {
- 0 as char
+ None
} else {
- self.source[self.current + 1] as char
+ Some(self.source[self.current + 1] as char)
}
}
fn string(&mut self) -> Result<Token> {
- while self.peek() != '"' && !self.is_at_end() {
- if self.peek() == '\n' {
+ while matches!(self.peek(), Some(c) if c != '"') {
+ if self.peek() == Some('\n') {
self.line += 1;
}
self.advance();
@@ -171,14 +170,14 @@ impl<'a> Scanner<'a> {
}
fn number(&mut self) -> Result<Token> {
- while self.peek().is_ascii_digit() {
+ while matches!(self.peek(), Some(c) if c.is_ascii_digit()) {
self.advance();
}
- if self.peek() == '.' && self.peek_next().is_ascii_digit() {
+ if self.peek() == Some('.') && matches!(self.peek_next(), Some(c) if c.is_ascii_digit()) {
self.advance();
- while self.peek().is_ascii_digit() {
+ while matches!(self.peek(), Some(c) if c.is_ascii_digit()) {
self.advance();
}
}
@@ -187,7 +186,7 @@ impl<'a> Scanner<'a> {
}
fn identifier(&mut self) -> Result<Token> {
- while is_alpha(self.peek()) || self.peek().is_ascii_digit() {
+ while matches!(self.peek(), Some(c) if is_alpha(c) || c.is_ascii_digit()) {
self.advance();
}
@@ -339,9 +338,7 @@ mod tests {
}
fn assert_scan_token(source: &str, kind: TokenKind) {
- let mut s = source.to_string();
- s.push(0 as char);
- let mut scanner = Scanner::new(&s);
+ let mut scanner = Scanner::new(source);
let token = scanner.scan().unwrap();
assert_eq!(token.kind, kind);
}