From 66d788cd56f116774a43257aca3f1f2fdad8f47e Mon Sep 17 00:00:00 2001
From: Martin Fischer <martin@push-f.com>
Date: Mon, 29 Nov 2021 12:49:40 +0100
Subject: refactor: use std::ops::ControlFlow

---
 src/tokenizer/mod.rs | 71 +++++++++++++++++++++++++++++-----------------------
 1 file changed, 39 insertions(+), 32 deletions(-)

diff --git a/src/tokenizer/mod.rs b/src/tokenizer/mod.rs
index e54eb46..02f7963 100644
--- a/src/tokenizer/mod.rs
+++ b/src/tokenizer/mod.rs
@@ -27,6 +27,7 @@ use std::borrow::Cow::{self, Borrowed};
 use std::collections::BTreeMap;
 use std::default::Default;
 use std::mem::replace;
+use std::ops::ControlFlow;
 
 pub use crate::util::buffer_queue::BufferQueue;
 use crate::util::buffer_queue::{FromSet, NotFromSet, SetResult};
@@ -37,7 +38,6 @@ mod interface;
 mod states;
 
 pub enum ProcessResult<Handle> {
-    Continue,
     Suspend,
     Script(Handle),
 }
@@ -351,17 +351,21 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
                     self.state_profile.insert(state, dt);
                 }
                 match run {
-                    ProcessResult::Continue => (),
-                    ProcessResult::Suspend => break,
-                    ProcessResult::Script(node) => return TokenizerResult::Script(node),
+                    ControlFlow::Continue(()) => (),
+                    ControlFlow::Break(ProcessResult::Suspend) => break,
+                    ControlFlow::Break(ProcessResult::Script(node)) => {
+                        return TokenizerResult::Script(node)
+                    }
                 }
             }
         } else {
             loop {
                 match self.step(input) {
-                    ProcessResult::Continue => (),
-                    ProcessResult::Suspend => break,
-                    ProcessResult::Script(node) => return TokenizerResult::Script(node),
+                    ControlFlow::Continue(()) => (),
+                    ControlFlow::Break(ProcessResult::Suspend) => break,
+                    ControlFlow::Break(ProcessResult::Script(node)) => {
+                        return TokenizerResult::Script(node)
+                    }
                 }
             }
         }
@@ -401,7 +405,7 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
         self.process_token_and_continue(CharacterTokens(b));
     }
 
-    fn emit_current_tag(&mut self) -> ProcessResult<Sink::Handle> {
+    fn emit_current_tag(&mut self) -> ControlFlow<ProcessResult<Sink::Handle>> {
         self.finish_attribute();
 
         let name = self.current_tag_name.clone();
@@ -429,18 +433,18 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
         });
 
         match self.process_token(token) {
-            TokenSinkResult::Continue => ProcessResult::Continue,
+            TokenSinkResult::Continue => ControlFlow::Continue(()),
             TokenSinkResult::Plaintext => {
                 self.state = states::Plaintext;
-                ProcessResult::Continue
+                ControlFlow::Continue(())
             }
             TokenSinkResult::Script(node) => {
                 self.state = states::Data;
-                ProcessResult::Script(node)
+                ControlFlow::Break(ProcessResult::Script(node))
             }
             TokenSinkResult::RawData(kind) => {
                 self.state = states::RawData(kind);
-                ProcessResult::Continue
+                ControlFlow::Continue(())
             }
         }
     }
@@ -602,12 +606,12 @@ macro_rules! sh_trace ( ( $me:ident : $($cmds:tt)* ) => ( shorthand!($me: $($cmd
 
 // A little DSL for sequencing shorthand actions.
 macro_rules! go (
-    ( $me:ident : to $s:ident                    ) => ({ $me.state = states::$s; ProcessResult::Continue           });
-    ( $me:ident : to $s:ident $k1:expr           ) => ({ $me.state = states::$s($k1); ProcessResult::Continue      });
-    ( $me:ident : to $s:ident $k1:ident $k2:expr ) => ({ $me.state = states::$s($k1($k2)); ProcessResult::Continue });
+    ( $me:ident : to $s:ident                    ) => ({ $me.state = states::$s; ControlFlow::Continue(())           });
+    ( $me:ident : to $s:ident $k1:expr           ) => ({ $me.state = states::$s($k1); ControlFlow::Continue(())      });
+    ( $me:ident : to $s:ident $k1:ident $k2:expr ) => ({ $me.state = states::$s($k1($k2)); ControlFlow::Continue(()) });
 
-    ( $me:ident : consume_char_ref             ) => ({ $me.consume_char_ref(None); ProcessResult::Continue         });
-    ( $me:ident : consume_char_ref $addnl:expr ) => ({ $me.consume_char_ref(Some($addnl)); ProcessResult::Continue });
+    ( $me:ident : consume_char_ref             ) => ({ $me.consume_char_ref(None); ControlFlow::Continue(())         });
+    ( $me:ident : consume_char_ref $addnl:expr ) => ({ $me.consume_char_ref(Some($addnl)); ControlFlow::Continue(()) });
 
     // We have a default next state after emitting a tag, but the sink can override.
     ( $me:ident : emit_tag $s:ident ) => ({
@@ -629,23 +633,23 @@ macro_rules! go_match ( ( $me:ident : $x:expr, $($pats:pat),+ => $($cmds:tt)* )
 // This is a macro because it can cause early return
 // from the function where it is used.
 macro_rules! get_char ( ($me:expr, $input:expr) => (
-    unwrap_or_return!($me.get_char($input), ProcessResult::Suspend)
+    unwrap_or_return!($me.get_char($input), ControlFlow::Break(ProcessResult::Suspend))
 ));
 
 macro_rules! peek ( ($me:expr, $input:expr) => (
-    unwrap_or_return!($me.peek($input), ProcessResult::Suspend)
+    unwrap_or_return!($me.peek($input), ControlFlow::Break(ProcessResult::Suspend))
 ));
 
 macro_rules! pop_except_from ( ($me:expr, $input:expr, $set:expr) => (
-    unwrap_or_return!($me.pop_except_from($input, $set), ProcessResult::Suspend)
+    unwrap_or_return!($me.pop_except_from($input, $set), ControlFlow::Break(ProcessResult::Suspend))
 ));
 
 macro_rules! eat ( ($me:expr, $input:expr, $pat:expr) => (
-    unwrap_or_return!($me.eat($input, $pat, u8::eq_ignore_ascii_case), ProcessResult::Suspend)
+    unwrap_or_return!($me.eat($input, $pat, u8::eq_ignore_ascii_case), ControlFlow::Break(ProcessResult::Suspend))
 ));
 
 macro_rules! eat_exact ( ($me:expr, $input:expr, $pat:expr) => (
-    unwrap_or_return!($me.eat($input, $pat, u8::eq), ProcessResult::Suspend)
+    unwrap_or_return!($me.eat($input, $pat, u8::eq), ControlFlow::Break(ProcessResult::Suspend))
 ));
 
 impl<Sink: TokenSink> Tokenizer<Sink> {
@@ -653,7 +657,7 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
     // Return true if we should be immediately re-invoked
     // (this just simplifies control flow vs. break / continue).
     #[allow(clippy::never_loop)]
-    fn step(&mut self, input: &mut BufferQueue) -> ProcessResult<Sink::Handle> {
+    fn step(&mut self, input: &mut BufferQueue) -> ControlFlow<ProcessResult<Sink::Handle>> {
         if self.char_ref_tokenizer.is_some() {
             return self.step_char_ref_tokenizer(input);
         }
@@ -1871,7 +1875,10 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
         }
     }
 
-    fn step_char_ref_tokenizer(&mut self, input: &mut BufferQueue) -> ProcessResult<Sink::Handle> {
+    fn step_char_ref_tokenizer(
+        &mut self,
+        input: &mut BufferQueue,
+    ) -> ControlFlow<ProcessResult<Sink::Handle>> {
         // FIXME HACK: Take and replace the tokenizer so we don't
         // double-mut-borrow self.  This is why it's boxed.
         let mut tok = self.char_ref_tokenizer.take().unwrap();
@@ -1880,11 +1887,11 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
         let progress = match outcome {
             char_ref::Done => {
                 self.process_char_ref(tok.get_result());
-                return ProcessResult::Continue;
+                return ControlFlow::Continue(());
             }
 
-            char_ref::Stuck => ProcessResult::Suspend,
-            char_ref::Progress => ProcessResult::Continue,
+            char_ref::Stuck => ControlFlow::Break(ProcessResult::Suspend),
+            char_ref::Progress => ControlFlow::Continue(()),
         };
 
         self.char_ref_tokenizer = Some(tok);
@@ -1942,9 +1949,9 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
 
         loop {
             match self.eof_step() {
-                ProcessResult::Continue => (),
-                ProcessResult::Suspend => break,
-                ProcessResult::Script(_) => unreachable!(),
+                ControlFlow::Continue(()) => (),
+                ControlFlow::Break(ProcessResult::Suspend) => break,
+                ControlFlow::Break(ProcessResult::Script(_)) => unreachable!(),
             }
         }
 
@@ -1974,7 +1981,7 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
         }
     }
 
-    fn eof_step(&mut self) -> ProcessResult<Sink::Handle> {
+    fn eof_step(&mut self) -> ControlFlow<ProcessResult<Sink::Handle>> {
         match self.state {
             states::Data
             | states::RawData(Rcdata)
@@ -1982,7 +1989,7 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
             | states::RawData(ScriptData)
             | states::Plaintext => {
                 self.emit_eof();
-                ProcessResult::Suspend
+                ControlFlow::Break(ProcessResult::Suspend)
             }
 
             states::TagName
-- 
cgit v1.2.3