inline: store attributes in vec

This commit is contained in:
Noah Hellman 2023-03-23 21:54:39 +01:00
parent 62d33effc4
commit 50205573d0
2 changed files with 31 additions and 20 deletions

View file

@ -57,21 +57,23 @@ pub enum QuoteType {
} }
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub enum EventKind<'s> { pub enum EventKind {
Enter(Container), Enter(Container),
Exit(Container), Exit(Container),
Atom(Atom), Atom(Atom),
Str, Str,
Attributes { Attributes {
container: bool, container: bool,
attrs: attr::Attributes<'s>, attrs: AttributesIndex,
}, },
Placeholder, Placeholder,
} }
type AttributesIndex = u32;
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub struct Event<'s> { pub struct Event {
pub kind: EventKind<'s>, pub kind: EventKind,
pub span: Span, pub span: Span,
} }
@ -208,13 +210,15 @@ pub struct Parser<'s> {
openers: Vec<(Opener, usize)>, openers: Vec<(Opener, usize)>,
/// Buffer queue for next events. Events are buffered until no modifications due to future /// Buffer queue for next events. Events are buffered until no modifications due to future
/// characters are needed. /// characters are needed.
events: std::collections::VecDeque<Event<'s>>, events: std::collections::VecDeque<Event>,
/// State if inside a verbatim container. /// State if inside a verbatim container.
verbatim: Option<VerbatimState>, verbatim: Option<VerbatimState>,
/// State if currently parsing potential attributes. /// State if currently parsing potential attributes.
attributes: Option<AttributesElementType>, attributes: Option<AttributesElementType>,
/// Storage of cow strs, used to reduce size of [`Container`]. /// Storage of cow strs, used to reduce size of [`Container`].
pub(crate) store_cowstrs: Vec<CowStr<'s>>, pub(crate) store_cowstrs: Vec<CowStr<'s>>,
/// Storage of attributes, used to reduce size of [`EventKind`].
pub(crate) store_attributes: Vec<attr::Attributes<'s>>,
} }
enum ControlFlow { enum ControlFlow {
@ -238,6 +242,7 @@ impl<'s> Parser<'s> {
verbatim: None, verbatim: None,
attributes: None, attributes: None,
store_cowstrs: Vec::new(), store_cowstrs: Vec::new(),
store_attributes: Vec::new(),
} }
} }
@ -252,14 +257,15 @@ impl<'s> Parser<'s> {
debug_assert!(self.attributes.is_none()); debug_assert!(self.attributes.is_none());
debug_assert!(self.verbatim.is_none()); debug_assert!(self.verbatim.is_none());
self.store_cowstrs.clear(); self.store_cowstrs.clear();
self.store_attributes.clear();
} }
fn push_sp(&mut self, kind: EventKind<'s>, span: Span) -> Option<ControlFlow> { fn push_sp(&mut self, kind: EventKind, span: Span) -> Option<ControlFlow> {
self.events.push_back(Event { kind, span }); self.events.push_back(Event { kind, span });
Some(Continue) Some(Continue)
} }
fn push(&mut self, kind: EventKind<'s>) -> Option<ControlFlow> { fn push(&mut self, kind: EventKind) -> Option<ControlFlow> {
self.push_sp(kind, self.input.span) self.push_sp(kind, self.input.span)
} }
@ -470,10 +476,12 @@ impl<'s> Parser<'s> {
self.input.lexer = lex::Lexer::new(&self.input.src[end_attr..line_end]); self.input.lexer = lex::Lexer::new(&self.input.src[end_attr..line_end]);
if !attrs.is_empty() { if !attrs.is_empty() {
let attr_index = self.store_attributes.len() as AttributesIndex;
self.store_attributes.push(attrs);
let attr_event = Event { let attr_event = Event {
kind: EventKind::Attributes { kind: EventKind::Attributes {
container: matches!(elem_ty, AttributesElementType::Container { .. }), container: matches!(elem_ty, AttributesElementType::Container { .. }),
attrs, attrs: attr_index,
}, },
span: self.input.span, span: self.input.span,
}; };
@ -861,7 +869,7 @@ impl<'s> Parser<'s> {
self.push(EventKind::Atom(atom)) self.push(EventKind::Atom(atom))
} }
fn merge_str_events(&mut self, span_str: Span) -> Event<'s> { fn merge_str_events(&mut self, span_str: Span) -> Event {
let mut span = span_str; let mut span = span_str;
let should_merge = |e: &Event, span: Span| { let should_merge = |e: &Event, span: Span| {
matches!(e.kind, EventKind::Str | EventKind::Placeholder) matches!(e.kind, EventKind::Str | EventKind::Placeholder)
@ -888,7 +896,7 @@ impl<'s> Parser<'s> {
} }
} }
fn apply_word_attributes(&mut self, span_str: Span) -> Event<'s> { fn apply_word_attributes(&mut self, span_str: Span) -> Event {
if let Some(i) = span_str if let Some(i) = span_str
.of(self.input.src) .of(self.input.src)
.bytes() .bytes()
@ -1063,7 +1071,7 @@ impl From<Opener> for DelimEventKind {
} }
impl<'s> Iterator for Parser<'s> { impl<'s> Iterator for Parser<'s> {
type Item = Event<'s>; type Item = Event;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
while self.events.is_empty() while self.events.is_empty()
@ -1196,7 +1204,7 @@ mod test {
( (
Attributes { Attributes {
container: true, container: true,
attrs: [("id", "id")].into_iter().collect() attrs: 0,
}, },
"{#id}" "{#id}"
), ),
@ -1387,7 +1395,7 @@ mod test {
( (
Attributes { Attributes {
container: false, container: false,
attrs: [("class", "cls")].into_iter().collect(), attrs: 0,
}, },
"{.cls}" "{.cls}"
), ),
@ -1436,7 +1444,7 @@ mod test {
( (
Attributes { Attributes {
container: true, container: true,
attrs: [("class", "def")].into_iter().collect(), attrs: 0,
}, },
"{.def}" "{.def}"
), ),
@ -1454,7 +1462,7 @@ mod test {
( (
Attributes { Attributes {
container: true, container: true,
attrs: [("class", "bar_")].into_iter().collect(), attrs: 0,
}, },
"{.bar_}" "{.bar_}"
), ),
@ -1564,7 +1572,7 @@ mod test {
( (
Attributes { Attributes {
container: true, container: true,
attrs: [("class", "attr")].into_iter().collect(), attrs: 0,
}, },
"{.attr}" "{.attr}"
), ),
@ -1598,7 +1606,7 @@ mod test {
( (
Attributes { Attributes {
container: true, container: true,
attrs: [("class", "a b c")].into_iter().collect(), attrs: 0,
}, },
"{.a}{.b}{.c}" "{.a}{.b}{.c}"
), ),
@ -1616,7 +1624,7 @@ mod test {
( (
Attributes { Attributes {
container: false, container: false,
attrs: [("a", "b")].into_iter().collect() attrs: 0,
}, },
"{a=b}" "{a=b}"
), ),
@ -1630,7 +1638,7 @@ mod test {
( (
Attributes { Attributes {
container: false, container: false,
attrs: [("class", "a b")].into_iter().collect(), attrs: 0,
}, },
"{.a}{.b}" "{.a}{.b}"
), ),

View file

@ -799,7 +799,10 @@ impl<'s> Parser<'s> {
inline::Event { inline::Event {
kind: inline::EventKind::Attributes { attrs, .. }, kind: inline::EventKind::Attributes { attrs, .. },
.. ..
} => (self.inline_parser.next(), attrs), } => (
self.inline_parser.next(),
self.inline_parser.store_attributes[attrs as usize].clone(),
),
inline => (Some(inline), Attributes::new()), inline => (Some(inline), Attributes::new()),
}; };