From 59ab43fa5b385ae41b7a1fa1709ce8796ae02caa Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Thu, 11 Nov 2021 18:07:57 +0000 Subject: [PATCH] hex-literal: improve comments filtration (#666) --- hex-literal/CHANGELOG.md | 1 + hex-literal/src/comments.rs | 108 +++++++++--------------------------- 2 files changed, 26 insertions(+), 83 deletions(-) diff --git a/hex-literal/CHANGELOG.md b/hex-literal/CHANGELOG.md index 46e77e34..98d90f95 100644 --- a/hex-literal/CHANGELOG.md +++ b/hex-literal/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [UNRELEASED] ### Changed - Provide more info in `panic!` messages +- Minor changes in the comments filtration code ### Added - More tests for `hex!()` macro diff --git a/hex-literal/src/comments.rs b/hex-literal/src/comments.rs index 135e6d53..6f8799d2 100644 --- a/hex-literal/src/comments.rs +++ b/hex-literal/src/comments.rs @@ -25,11 +25,10 @@ impl> Iterator for ExcludingComments { let next_byte = self.next_byte(); if next_byte.is_none() { match self.state { - State::BlockComment | State::PotentiallyLeavingBlockComment => { + State::BlockComment | State::PotentialBlockCommentEnd => { panic!("block comment not terminated with */") } - // No more bytes after a single '/' - State::PotentialComment { .. } => panic!("encountered invalid character: `/`"), + State::PotentialComment { .. } => panic!("encountered isolated `/`"), _ => {} } } @@ -45,16 +44,17 @@ impl> Iterator for ExcludingComments { /// '/' '*' /// LineComment BlockComment /// '\n' '*' -/// Normal PotentiallyLeavingBlockComment +/// Normal PotentialBlockCommentEnd /// '/' '_' /// Normal BlockComment -/// +/// +#[derive(Copy, Clone)] enum State { Normal, - PotentialComment { previous: u8 }, + PotentialComment, LineComment, BlockComment, - PotentiallyLeavingBlockComment, + PotentialBlockCommentEnd, } impl> ExcludingComments { @@ -67,81 +67,22 @@ impl> ExcludingComments { fn next_byte(&mut self) -> Option { loop { - return match self.state { - State::Normal => { - let next = self.iter.next()?; - match next { - b'/' => { - self.state = State::PotentialComment { previous: next }; - continue; - } - _ => Some(next), - } - } - State::PotentialComment { previous } => { - let peeked_next = self.iter.peek()?; - match peeked_next { - b'/' => { - // second /, enter line comment and consume - self.iter.next(); - self.state = State::LineComment; - continue; - } - b'*' => { - /* entering a block comment consume '*' */ - self.iter.next(); - self.state = State::BlockComment; - continue; - } - _ => { - // here we need to emit the previous character (the first '/') - // and do not consume the current character - self.state = State::Normal; - return Some(previous); - } - } - } - State::LineComment => { - let next = self.iter.next()?; - match next { - b'\n' => { - self.state = State::Normal; - return Some(next); - } - _ => { - // ignore all other characters while in the line comment - continue; - } - } - } - State::BlockComment => { - let next = self.iter.next()?; - match next { - b'*' => { - self.state = State::PotentiallyLeavingBlockComment; - continue; - } - _ => { - /* ignore all other characters while in the block comment */ - continue; - } - } - } - State::PotentiallyLeavingBlockComment => { - let next = self.iter.next()?; - match next { - b'/' => { - /* Left the block comment */ - self.state = State::Normal; - continue; - } - _ => { - /* we're still in the block comment */ - self.state = State::BlockComment; - continue; - } - } + let next = self.iter.next()?; + self.state = match (self.state, next) { + (State::Normal, b'/') => State::PotentialComment, + (State::Normal, _) => return Some(next), + (State::PotentialComment, b'/') => State::LineComment, + (State::PotentialComment, b'*') => State::BlockComment, + (State::PotentialComment, _) => panic!("encountered isolated `/`"), + (State::LineComment, b'\n') => { + self.state = State::Normal; + return Some(b'\n'); } + (State::LineComment, _) => continue, + (State::BlockComment, b'*') => State::PotentialBlockCommentEnd, + (State::BlockComment, _) => continue, + (State::PotentialBlockCommentEnd, b'/') => State::Normal, + (State::PotentialBlockCommentEnd, _) => State::BlockComment, }; } } @@ -195,8 +136,9 @@ mod tests { } #[test] - fn single_slash_is_not_excluded() { - assert_eq!(exclude_comments("ab/cd"), "ab/cd"); + #[should_panic] + fn panic_on_single_slash() { + exclude_comments("ab/cd"); } #[test]