inline: store attributes in vec
This commit is contained in:
		
					parent
					
						
							
								62d33effc4
							
						
					
				
			
			
				commit
				
					
						50205573d0
					
				
			
		
					 2 changed files with 31 additions and 20 deletions
				
			
		| 
						 | 
					@ -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}"
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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()),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue