Skip to content

Commit

Permalink
advance_until refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
Lurk committed Sep 28, 2024
1 parent 21337f7 commit 0e09b3b
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 60 deletions.
3 changes: 2 additions & 1 deletion src/parser/anchor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ pub(crate) fn anchor(p: &mut Parser<'_>) -> Option<Anchor> {
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 {
Expand Down
43 changes: 17 additions & 26 deletions src/parser/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,24 @@ use super::Parser;

pub(crate) fn code(p: &mut Parser<'_>) -> Option<Code> {
let start_pos = p.pos();
let mut lang: Option<usize> = 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)]
Expand All @@ -44,6 +34,7 @@ mod tests {
};

use super::code;
use pretty_assertions::assert_eq;

#[test]
fn happy_path() {
Expand Down
2 changes: 1 addition & 1 deletion src/parser/code_span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{lexer::TokenKind, nodes::CodeSpan};
use super::Parser;

pub(crate) fn code_span(p: &mut Parser) -> Option<CodeSpan> {
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)))
}

Expand Down
2 changes: 1 addition & 1 deletion src/parser/collapsible.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub(crate) fn collapsible(p: &mut Parser) -> Option<Collapsible> {
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;
Expand Down
6 changes: 4 additions & 2 deletions src/parser/highlight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ pub(crate) fn highlight(p: &mut Parser) -> Option<Highlight> {
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 {
Expand All @@ -45,7 +46,8 @@ pub(crate) fn highlight(p: &mut Parser) -> Option<Highlight> {
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 {
Expand Down
2 changes: 1 addition & 1 deletion src/parser/italic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{lexer::TokenKind, nodes::Italic};
use super::Parser;

pub(crate) fn italic(p: &mut Parser) -> Option<Italic> {
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)))
}

Expand Down
47 changes: 20 additions & 27 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,43 +93,44 @@ impl<'input> Parser<'input> {
false
}

pub fn advance_until<Callback>(&mut self, f: Callback) -> Option<(usize, usize)>
pub fn advance_until<Callback>(
&mut self,
f: Callback,
skip_terminator: bool,
) -> Option<(usize, usize)>
where
Callback: Fn(&Token) -> bool,
{
let start = self.pos();
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<Callback>(&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 {
Expand Down Expand Up @@ -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))
Expand Down
2 changes: 1 addition & 1 deletion src/parser/strikethrough.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{lexer::TokenKind, nodes::Strikethrough};
use super::Parser;

pub(crate) fn strikethrough(p: &mut Parser) -> Option<Strikethrough> {
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)))
}

Expand Down

0 comments on commit 0e09b3b

Please sign in to comment.