don't use a null sentinel
change pyzwpxxmktszzupsmqsolvtwrpklqlsy
commit 6cec04946141c5d02a0b1ac8fd1be750d5d2f28f
author Alpha Chen <alpha@kejadlen.dev>
date
parent wkmotzos
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);
     }