From 0e09b3befcedc6d64805e9d2603079e2c8cc3bfa Mon Sep 17 00:00:00 2001 From: Lurk Date: Sat, 28 Sep 2024 11:04:50 +0200 Subject: [PATCH] advance_until refactoring --- src/parser/anchor.rs | 3 ++- src/parser/code.rs | 43 ++++++++++++++------------------- src/parser/code_span.rs | 2 +- src/parser/collapsible.rs | 2 +- src/parser/highlight.rs | 6 +++-- src/parser/italic.rs | 2 +- src/parser/mod.rs | 47 ++++++++++++++++--------------------- src/parser/strikethrough.rs | 2 +- 8 files changed, 47 insertions(+), 60 deletions(-) diff --git a/src/parser/anchor.rs b/src/parser/anchor.rs index d91251f..164733f 100644 --- a/src/parser/anchor.rs +++ b/src/parser/anchor.rs @@ -11,7 +11,8 @@ pub(crate) fn anchor(p: &mut Parser<'_>) -> Option { match t.kind { TokenKind::Terminator => break, TokenKind::LeftSquareBracket if right_square_bracket_pos.is_none() => { - if let Some((_, end)) = p.advance_until(|t| t.kind == TokenKind::RightSquareBracket) + if let Some((_, end)) = + p.advance_until_terminated(|t| t.kind == TokenKind::RightSquareBracket) { right_square_bracket_pos.replace(end); } else { diff --git a/src/parser/code.rs b/src/parser/code.rs index bd55dd4..c73fdf4 100644 --- a/src/parser/code.rs +++ b/src/parser/code.rs @@ -4,34 +4,24 @@ use super::Parser; pub(crate) fn code(p: &mut Parser<'_>) -> Option { let start_pos = p.pos(); - let mut lang: Option = None; + let lang = p + .advance_until_terminated(|t| t.kind == TokenKind::Eol) + .map(|(_, end)| end)?; - p.next_token(); - while let Some((t, pos)) = p.peek() { - match t.kind { - TokenKind::Terminator if lang.is_none() => break, - TokenKind::Backtick if t.position.column == 0 && t.slice.len() == 3 => { - if let Some(lang) = lang { - p.next_token(); - return Some(Code::new( - p.range_to_string(start_pos + 1..lang), - p.range_to_string(lang + 1..pos - 1), - )); - } - } - TokenKind::Eol if lang.is_none() => { - lang.replace(pos); - p.next_token(); - } - _ => { - p.next_token(); - } - } - } + let Some((start, end)) = p.advance_until( + |t| t.kind == TokenKind::Backtick && t.position.column == 0 && t.slice.len() == 3, + true, + ) else { + p.move_to(start_pos); + p.flip_to_literal_at(start_pos); + return None; + }; - p.move_to(start_pos); - p.flip_to_literal_at(start_pos); - None + p.next_token(); + Some(Code::new( + p.range_to_string(start_pos + 1..lang), + p.range_to_string(start..end - 1), + )) } #[cfg(test)] @@ -44,6 +34,7 @@ mod tests { }; use super::code; + use pretty_assertions::assert_eq; #[test] fn happy_path() { diff --git a/src/parser/code_span.rs b/src/parser/code_span.rs index 8133e24..7a554d6 100644 --- a/src/parser/code_span.rs +++ b/src/parser/code_span.rs @@ -3,7 +3,7 @@ use crate::{lexer::TokenKind, nodes::CodeSpan}; use super::Parser; pub(crate) fn code_span(p: &mut Parser) -> Option { - p.advance_until(|t| t.kind == TokenKind::Backtick && t.slice.len() == 1) + p.advance_until_terminated(|t| t.kind == TokenKind::Backtick && t.slice.len() == 1) .map(|(start, end)| CodeSpan::new(p.range_to_string(start + 1..end))) } diff --git a/src/parser/collapsible.rs b/src/parser/collapsible.rs index f189588..1ca0be3 100644 --- a/src/parser/collapsible.rs +++ b/src/parser/collapsible.rs @@ -16,7 +16,7 @@ pub(crate) fn collapsible(p: &mut Parser) -> Option { while let Some((t, _)) = p.peek() { match t.kind { TokenKind::Space if title.is_none() => { - if let Some((start, end)) = p.advance_until_new_line() { + if let Some((start, end)) = p.advance_until(|t| t.position.column == 0, true) { title.replace(start + 1..end - 1); } else { break; diff --git a/src/parser/highlight.rs b/src/parser/highlight.rs index 0d30d3e..e1e33cf 100644 --- a/src/parser/highlight.rs +++ b/src/parser/highlight.rs @@ -33,7 +33,8 @@ pub(crate) fn highlight(p: &mut Parser) -> Option { p.next_token(); } TokenKind::Space if state == State::TitleCommit && title.is_none() => { - if let Some((start, end)) = p.advance_until(|t| t.kind == TokenKind::Eol) { + if let Some((start, end)) = p.advance_until_terminated(|t| t.kind == TokenKind::Eol) + { state = State::Icon; title.replace(start + 1..end); } else { @@ -45,7 +46,8 @@ pub(crate) fn highlight(p: &mut Parser) -> Option { p.next_token(); } TokenKind::Space if state == State::IconCommit && icon.is_none() => { - if let Some((start, end)) = p.advance_until(|t| t.kind == TokenKind::Eol) { + if let Some((start, end)) = p.advance_until_terminated(|t| t.kind == TokenKind::Eol) + { state = State::Body; icon.replace(start + 1..end); } else { diff --git a/src/parser/italic.rs b/src/parser/italic.rs index 7ef8383..2253365 100644 --- a/src/parser/italic.rs +++ b/src/parser/italic.rs @@ -3,7 +3,7 @@ use crate::{lexer::TokenKind, nodes::Italic}; use super::Parser; pub(crate) fn italic(p: &mut Parser) -> Option { - p.advance_until(|t| t.kind == TokenKind::Underscore && t.slice.len() == 1) + p.advance_until_terminated(|t| t.kind == TokenKind::Underscore && t.slice.len() == 1) .map(|(start, end)| Italic::new(p.range_to_string(start + 1..end))) } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index a2cc71c..8f171e0 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -93,7 +93,11 @@ impl<'input> Parser<'input> { false } - pub fn advance_until(&mut self, f: Callback) -> Option<(usize, usize)> + pub fn advance_until( + &mut self, + f: Callback, + skip_terminator: bool, + ) -> Option<(usize, usize)> where Callback: Fn(&Token) -> bool, { @@ -101,35 +105,32 @@ impl<'input> Parser<'input> { self.next_token(); while let Some((t, pos)) = self.peek() { - if t.kind == TokenKind::Terminator { + if t.kind == TokenKind::Terminator && !skip_terminator { break; }; if f(t) { - self.next_token(); return Some((start, pos)); } self.next_token(); } - self.move_to(start); - self.flip_to_literal_at(start); None } - pub fn advance_until_new_line(&mut self) -> Option<(usize, usize)> { + pub fn advance_until_terminated(&mut self, f: Callback) -> Option<(usize, usize)> + where + Callback: Fn(&Token) -> bool, + { let start = self.pos(); - self.next_token(); - while let Some((t, pos)) = self.peek() { - if t.position.column == 0 { - return Some((start, pos)); - } - self.next_token(); - } - self.move_to(start); - self.flip_to_literal_at(start); - None + let Some(result) = self.advance_until(f, false) else { + self.move_to(start); + self.flip_to_literal_at(start); + return None; + }; + self.next_token(); + Some(result) } pub fn pos(&self) -> usize { @@ -197,18 +198,10 @@ mod tests { fn advance_until() { let mut p = Parser::new("!test"); - assert_eq!(p.advance_until(|t| t.kind == TokenKind::Space), None); assert_eq!( - p.peek(), - Some((&Token::new(TokenKind::Literal, "!", Position::default()), 0)) - ) - } - - #[test] - fn advance_until_new_line() { - let mut p = Parser::new("!test"); - - assert_eq!(p.advance_until_new_line(), None); + p.advance_until_terminated(|t| t.kind == TokenKind::Space), + None + ); assert_eq!( p.peek(), Some((&Token::new(TokenKind::Literal, "!", Position::default()), 0)) diff --git a/src/parser/strikethrough.rs b/src/parser/strikethrough.rs index 3eaf867..e02aceb 100644 --- a/src/parser/strikethrough.rs +++ b/src/parser/strikethrough.rs @@ -3,7 +3,7 @@ use crate::{lexer::TokenKind, nodes::Strikethrough}; use super::Parser; pub(crate) fn strikethrough(p: &mut Parser) -> Option { - p.advance_until(|t| t.kind == TokenKind::Tilde && t.slice.len() == 2) + p.advance_until_terminated(|t| t.kind == TokenKind::Tilde && t.slice.len() == 2) .map(|(start, end)| Strikethrough::new(p.range_to_string(start + 1..end))) }