prepass: avoid peekable for block iter

This commit is contained in:
Noah Hellman 2023-06-14 20:04:31 +02:00
parent 5ddbd728a8
commit 253d1d2d4b

View file

@ -598,49 +598,56 @@ impl<'s> PrePass<'s> {
#[must_use] #[must_use]
fn new( fn new(
src: &'s str, src: &'s str,
blocks: std::slice::Iter<block::Event<'s>>, mut blocks: std::slice::Iter<block::Event<'s>>,
inline_parser: &mut inline::Parser<'s>, inline_parser: &mut inline::Parser<'s>,
) -> Self { ) -> Self {
let mut link_definitions = Map::new(); let mut link_definitions = Map::new();
let mut headings: Vec<Heading> = Vec::new(); let mut headings: Vec<Heading> = Vec::new();
let mut used_ids: Set<String> = Set::new(); let mut used_ids: Set<String> = Set::new();
let mut blocks = blocks.peekable();
let mut attr_prev: Option<Range<usize>> = None; let mut attr_prev: Option<Range<usize>> = None;
while let Some(e) = blocks.next() { while let Some(e) = blocks.next() {
match e.kind { match e.kind {
block::EventKind::Enter(block::Node::Leaf(block::Leaf::LinkDefinition { block::EventKind::Enter(block::Node::Leaf(block::Leaf::LinkDefinition {
label, label,
})) => { })) => {
fn next_is_inline(
bs: &mut std::iter::Peekable<std::slice::Iter<block::Event>>,
) -> bool {
matches!(bs.peek().map(|e| &e.kind), Some(block::EventKind::Inline))
}
// All link definition tags have to be obtained initially, as references can // All link definition tags have to be obtained initially, as references can
// appear before the definition. // appear before the definition.
let attrs = attr_prev let attrs = attr_prev
.as_ref() .as_ref()
.map_or_else(Attributes::new, |sp| attr::parse(&src[sp.clone()])); .map_or_else(Attributes::new, |sp| attr::parse(&src[sp.clone()]));
let url = if !next_is_inline(&mut blocks) { let url = if let Some(block::Event {
"".into() kind: block::EventKind::Inline,
} else { span,
let start = src[blocks.next().as_ref().unwrap().span.clone()] }) = blocks.next()
.trim_matches(|c: char| c.is_ascii_whitespace()); {
if !next_is_inline(&mut blocks) { let start =
start.into() src[span.clone()].trim_matches(|c: char| c.is_ascii_whitespace());
} else { if let Some(block::Event {
kind: block::EventKind::Inline,
span,
}) = blocks.next()
{
let mut url = start.to_string(); let mut url = start.to_string();
while next_is_inline(&mut blocks) { url.push_str(
src[span.clone()].trim_matches(|c: char| c.is_ascii_whitespace()),
);
while let Some(block::Event {
kind: block::EventKind::Inline,
span,
}) = blocks.next()
{
url.push_str( url.push_str(
src[blocks.next().as_ref().unwrap().span.clone()] src[span.clone()]
.trim_matches(|c: char| c.is_ascii_whitespace()), .trim_matches(|c: char| c.is_ascii_whitespace()),
); );
} }
url.into() url.into() // owned
} else {
start.into() // borrowed
} }
} else {
"".into() // static
}; };
link_definitions.insert(label, (url, attrs)); link_definitions.insert(label, (url, attrs));
} }