diff --git a/src/inline.rs b/src/inline.rs index ba70620e..32726a8b 100644 --- a/src/inline.rs +++ b/src/inline.rs @@ -9,6 +9,7 @@ use lex::Symbol; use Atom::*; use Container::*; +use ControlFlow::*; #[derive(Debug, Clone, PartialEq, Eq)] pub enum Atom { @@ -223,6 +224,15 @@ pub struct Parser<'s> { verbatim: Option, } +pub enum ControlFlow { + /// At least one event has been emitted, continue parsing the line. + Continue, + /// More lines are needed to emit an event. + More, + /// Parsing of the line is completed. + Done, +} + impl<'s> Parser<'s> { pub fn new(src: &'s str) -> Self { Self { @@ -245,18 +255,18 @@ impl<'s> Parser<'s> { debug_assert!(self.verbatim.is_none()); } - fn push_sp(&mut self, kind: EventKind<'s>, span: Span) -> Option<()> { + fn push_sp(&mut self, kind: EventKind<'s>, span: Span) -> Option { self.events.push_back(Event { kind, span }); - Some(()) + Some(Continue) } - fn push(&mut self, kind: EventKind<'s>) -> Option<()> { + fn push(&mut self, kind: EventKind<'s>) -> Option { self.push_sp(kind, self.input.span) } - fn parse_event(&mut self) -> Option<()> { + fn parse_event(&mut self) -> ControlFlow { self.input.reset_span(); - self.input.eat().map(|first| { + if let Some(first) = self.input.eat() { let ctrl = self .parse_verbatim(&first) .or_else(|| self.parse_attributes(&first)) @@ -265,19 +275,21 @@ impl<'s> Parser<'s> { .or_else(|| self.parse_footnote_reference(&first)) .or_else(|| self.parse_container(&first)) .or_else(|| self.parse_atom(&first)) - .unwrap_or_else(|| { - self.push(EventKind::Str); - }); + .unwrap_or_else(|| self.push(EventKind::Str).unwrap()); if matches!(first.kind, lex::Kind::Newline) { self.input.span_line = Span::new(self.input.span.end(), self.input.span_line.end()); } ctrl - }) + } else if self.input.last() { + Done + } else { + More + } } - fn parse_verbatim(&mut self, first: &lex::Token) -> Option<()> { + fn parse_verbatim(&mut self, first: &lex::Token) -> Option { if let Some(VerbatimState { event_opener, len_opener, @@ -339,7 +351,7 @@ impl<'s> Parser<'s> { ) }) { - return Some(()); // skip whitespace + return Some(Continue); // skip whitespace } } else { *non_whitespace_encountered = true; @@ -347,7 +359,7 @@ impl<'s> Parser<'s> { } self.push(EventKind::Str); }; - Some(()) + Some(Continue) } else { let (ty, len_opener) = match first.kind { lex::Kind::DollarBacktick(l) if first.len - l as usize == 1 => { @@ -372,7 +384,7 @@ impl<'s> Parser<'s> { } } - fn parse_attributes(&mut self, first: &lex::Token) -> Option<()> { + fn parse_attributes(&mut self, first: &lex::Token) -> Option { if first.kind == lex::Kind::Open(Delimiter::Brace) { let mut ahead = self.input.lexer.ahead().chars(); let (mut attr_len, mut has_attr) = attr::valid(std::iter::once('{').chain(&mut ahead)); @@ -398,14 +410,14 @@ impl<'s> Parser<'s> { } else { self.push_sp(EventKind::Placeholder, self.input.span.empty_before()); } - return Some(()); + return Some(Continue); } } None } - fn parse_autolink(&mut self, first: &lex::Token) -> Option<()> { + fn parse_autolink(&mut self, first: &lex::Token) -> Option { if first.kind == lex::Kind::Sym(Symbol::Lt) { let mut ahead = self.input.lexer.ahead().chars(); let mut end = false; @@ -437,7 +449,7 @@ impl<'s> Parser<'s> { None } - fn parse_symbol(&mut self, first: &lex::Token) -> Option<()> { + fn parse_symbol(&mut self, first: &lex::Token) -> Option { if first.kind == lex::Kind::Sym(Symbol::Colon) { let mut ahead = self.input.lexer.ahead().chars(); let mut end = false; @@ -458,13 +470,13 @@ impl<'s> Parser<'s> { self.input.span = self.input.span.after(len); self.push(EventKind::Atom(Symbol)); self.input.span = self.input.span.after(1); - return Some(()); + return Some(Continue); } } None } - fn parse_footnote_reference(&mut self, first: &lex::Token) -> Option<()> { + fn parse_footnote_reference(&mut self, first: &lex::Token) -> Option { if first.kind == lex::Kind::Open(Delimiter::Bracket) && matches!( self.input.peek(), @@ -501,13 +513,13 @@ impl<'s> Parser<'s> { self.input.span = self.input.span.after(len); self.push(EventKind::Atom(FootnoteReference)); self.input.span = self.input.span.after(1); - return Some(()); + return Some(Continue); } } None } - fn parse_container(&mut self, first: &lex::Token) -> Option<()> { + fn parse_container(&mut self, first: &lex::Token) -> Option { self.openers .iter() .rposition(|(o, _)| o.closed_by(first.kind)) @@ -634,7 +646,7 @@ impl<'s> Parser<'s> { span: span_spec, }; self.events.drain(e_opener..); - Some(()) + Some(Continue) } }; @@ -705,7 +717,7 @@ impl<'s> Parser<'s> { }) } - fn parse_atom(&mut self, first: &lex::Token) -> Option<()> { + fn parse_atom(&mut self, first: &lex::Token) -> Option { let atom = match first.kind { lex::Kind::Newline => Softbreak, lex::Kind::Hardbreak => Hardbreak, @@ -739,7 +751,7 @@ impl<'s> Parser<'s> { self.push_sp(EventKind::Atom(atom), self.input.span.with_len(l)); self.input.span = self.input.span.skip(l); }); - return Some(()); + return Some(Continue); } lex::Kind::Open(Delimiter::BraceQuote1) => Quote { ty: QuoteType::Single, @@ -973,12 +985,10 @@ impl<'s> Iterator for Parser<'s> { .back() .map_or(false, |ev| matches!(ev.kind, EventKind::Str)) { - if self.parse_event().is_none() { - if self.input.last() { - break; - } else { - return None; - } + match self.parse_event() { + Continue => {} + Done => break, + More => return None, } }