fixup! tree: add tree branch reference
This commit is contained in:
		
					parent
					
						
							
								a62eb3e1d8
							
						
					
				
			
			
				commit
				
					
						5e8c683050
					
				
			
		
					 3 changed files with 26 additions and 54 deletions
				
			
		| 
						 | 
					@ -12,7 +12,6 @@ use Leaf::*;
 | 
				
			||||||
use ListType::*;
 | 
					use ListType::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub type Tree = tree::Tree<Node, Atom>;
 | 
					pub type Tree = tree::Tree<Node, Atom>;
 | 
				
			||||||
pub type Branch = tree::Branch<Node, Atom>;
 | 
					 | 
				
			||||||
pub type TreeBuilder = tree::Builder<Node, Atom>;
 | 
					pub type TreeBuilder = tree::Builder<Node, Atom>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 | 
					#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 | 
				
			||||||
| 
						 | 
					@ -523,7 +522,7 @@ mod test {
 | 
				
			||||||
    macro_rules! test_parse {
 | 
					    macro_rules! test_parse {
 | 
				
			||||||
            ($src:expr $(,$($event:expr),* $(,)?)?) => {
 | 
					            ($src:expr $(,$($event:expr),* $(,)?)?) => {
 | 
				
			||||||
                let t = super::TreeParser::new($src).parse();
 | 
					                let t = super::TreeParser::new($src).parse();
 | 
				
			||||||
                let actual = t.root().map(|ev| (ev.kind, ev.span.of($src))).collect::<Vec<_>>();
 | 
					                let actual = t.map(|ev| (ev.kind, ev.span.of($src))).collect::<Vec<_>>();
 | 
				
			||||||
                let expected = &[$($($event),*,)?];
 | 
					                let expected = &[$($($event),*,)?];
 | 
				
			||||||
                assert_eq!(actual, expected, "\n\n{}\n\n", $src);
 | 
					                assert_eq!(actual, expected, "\n\n{}\n\n", $src);
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										14
									
								
								src/lib.rs
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								src/lib.rs
									
										
									
									
									
								
							| 
						 | 
					@ -263,14 +263,11 @@ impl<'s> Container<'s> {
 | 
				
			||||||
pub struct Parser<'s> {
 | 
					pub struct Parser<'s> {
 | 
				
			||||||
    src: &'s str,
 | 
					    src: &'s str,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Block tree parsed at first, written once. This is never accessed directly, the data is read
 | 
					 | 
				
			||||||
    /// via [`Branch`] cursors. This is here only to keep it alive during the `Parser`'s lifetime.
 | 
					 | 
				
			||||||
    _tree_data: block::Tree,
 | 
					 | 
				
			||||||
    /// Link definitions encountered during block parse, written once.
 | 
					    /// Link definitions encountered during block parse, written once.
 | 
				
			||||||
    link_definitions: std::collections::HashMap<&'s str, CowStr<'s>>,
 | 
					    link_definitions: std::collections::HashMap<&'s str, CowStr<'s>>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Block tree cursor.
 | 
					    /// Block tree cursor.
 | 
				
			||||||
    tree: block::Branch,
 | 
					    tree: block::Tree,
 | 
				
			||||||
    /// Spans to the inlines in the block currently being parsed.
 | 
					    /// Spans to the inlines in the block currently being parsed.
 | 
				
			||||||
    inlines: span::InlineSpans<'s>,
 | 
					    inlines: span::InlineSpans<'s>,
 | 
				
			||||||
    /// Inline parser, recreated for each new inline.
 | 
					    /// Inline parser, recreated for each new inline.
 | 
				
			||||||
| 
						 | 
					@ -279,7 +276,7 @@ pub struct Parser<'s> {
 | 
				
			||||||
    /// Footnote references in the order they were encountered, without duplicates.
 | 
					    /// Footnote references in the order they were encountered, without duplicates.
 | 
				
			||||||
    footnote_references: Vec<&'s str>,
 | 
					    footnote_references: Vec<&'s str>,
 | 
				
			||||||
    /// Cache of footnotes to emit at the end.
 | 
					    /// Cache of footnotes to emit at the end.
 | 
				
			||||||
    footnotes: std::collections::HashMap<&'s str, block::Branch>,
 | 
					    footnotes: std::collections::HashMap<&'s str, block::Tree>,
 | 
				
			||||||
    /// Next or current footnote being parsed and emitted.
 | 
					    /// Next or current footnote being parsed and emitted.
 | 
				
			||||||
    footnote_index: usize,
 | 
					    footnote_index: usize,
 | 
				
			||||||
    /// Currently within a footnote.
 | 
					    /// Currently within a footnote.
 | 
				
			||||||
| 
						 | 
					@ -292,7 +289,7 @@ impl<'s> Parser<'s> {
 | 
				
			||||||
        let tree = block::parse(src);
 | 
					        let tree = block::parse(src);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let link_definitions = {
 | 
					        let link_definitions = {
 | 
				
			||||||
            let mut branch = tree.root();
 | 
					            let mut branch = tree.clone();
 | 
				
			||||||
            let mut defs = std::collections::HashMap::new();
 | 
					            let mut defs = std::collections::HashMap::new();
 | 
				
			||||||
            while let Some(e) = branch.next() {
 | 
					            while let Some(e) = branch.next() {
 | 
				
			||||||
                if let tree::EventKind::Enter(block::Node::Leaf(block::Leaf::LinkDefinition)) =
 | 
					                if let tree::EventKind::Enter(block::Node::Leaf(block::Leaf::LinkDefinition)) =
 | 
				
			||||||
| 
						 | 
					@ -310,11 +307,10 @@ impl<'s> Parser<'s> {
 | 
				
			||||||
            defs
 | 
					            defs
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let branch = tree.root();
 | 
					        let branch = tree.clone();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            src,
 | 
					            src,
 | 
				
			||||||
            _tree_data: tree,
 | 
					 | 
				
			||||||
            link_definitions,
 | 
					            link_definitions,
 | 
				
			||||||
            tree: branch,
 | 
					            tree: branch,
 | 
				
			||||||
            footnote_references: Vec::new(),
 | 
					            footnote_references: Vec::new(),
 | 
				
			||||||
| 
						 | 
					@ -523,7 +519,7 @@ impl<'s> Parser<'s> {
 | 
				
			||||||
            self.tree = self
 | 
					            self.tree = self
 | 
				
			||||||
                .footnotes
 | 
					                .footnotes
 | 
				
			||||||
                .remove(tag)
 | 
					                .remove(tag)
 | 
				
			||||||
                .unwrap_or_else(block::Branch::empty);
 | 
					                .unwrap_or_else(block::Tree::empty);
 | 
				
			||||||
            self.footnote_active = true;
 | 
					            self.footnote_active = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Some(Event::Start(
 | 
					            Some(Event::Start(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										63
									
								
								src/tree.rs
									
										
									
									
									
								
							
							
						
						
									
										63
									
								
								src/tree.rs
									
										
									
									
									
								
							| 
						 | 
					@ -14,45 +14,17 @@ pub struct Event<C, A> {
 | 
				
			||||||
    pub span: Span,
 | 
					    pub span: Span,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct Tree<C, A>(Box<[Node<C, A>]>);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Clone)]
 | 
					#[derive(Clone)]
 | 
				
			||||||
pub struct Inlines<'t, C, A> {
 | 
					pub struct Tree<C: 'static, A: 'static> {
 | 
				
			||||||
    iter: std::slice::Iter<'t, Node<C, A>>,
 | 
					    nodes: std::rc::Rc<[Node<C, A>]>,
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'t, C, A> Iterator for Inlines<'t, C, A> {
 | 
					 | 
				
			||||||
    type Item = Span;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn next(&mut self) -> Option<Self::Item> {
 | 
					 | 
				
			||||||
        self.iter.next().map(|n| n.span)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<C, A> Tree<C, A> {
 | 
					 | 
				
			||||||
    pub fn root(&self) -> Branch<C, A> {
 | 
					 | 
				
			||||||
        let head = self.0[NodeIndex::root().index()].next;
 | 
					 | 
				
			||||||
        // SAFETY: tree must outlive the branch
 | 
					 | 
				
			||||||
        let nodes = unsafe { std::mem::transmute::<&[Node<C, A>], &'static [Node<C, A>]>(&self.0) };
 | 
					 | 
				
			||||||
        Branch {
 | 
					 | 
				
			||||||
            nodes,
 | 
					 | 
				
			||||||
            branch: Vec::new(),
 | 
					 | 
				
			||||||
            head,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Clone)]
 | 
					 | 
				
			||||||
pub struct Branch<C: 'static, A: 'static> {
 | 
					 | 
				
			||||||
    nodes: &'static [Node<C, A>],
 | 
					 | 
				
			||||||
    branch: Vec<NodeIndex>,
 | 
					    branch: Vec<NodeIndex>,
 | 
				
			||||||
    head: Option<NodeIndex>,
 | 
					    head: Option<NodeIndex>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<C, A> Branch<C, A> {
 | 
					impl<C: Clone, A: Clone> Tree<C, A> {
 | 
				
			||||||
    pub fn empty() -> Self {
 | 
					    pub fn empty() -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            nodes: &[],
 | 
					            nodes: vec![].into_boxed_slice().into(),
 | 
				
			||||||
            branch: Vec::new(),
 | 
					            branch: Vec::new(),
 | 
				
			||||||
            head: None,
 | 
					            head: None,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -78,7 +50,7 @@ impl<C, A> Branch<C, A> {
 | 
				
			||||||
            self.head = n.next;
 | 
					            self.head = n.next;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            nodes: self.nodes,
 | 
					            nodes: self.nodes.clone(),
 | 
				
			||||||
            branch: Vec::new(),
 | 
					            branch: Vec::new(),
 | 
				
			||||||
            head,
 | 
					            head,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -99,7 +71,7 @@ impl<C, A> Branch<C, A> {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<C: Clone, A: Clone> Iterator for Branch<C, A> {
 | 
					impl<C: Clone, A: Clone> Iterator for Tree<C, A> {
 | 
				
			||||||
    type Item = Event<C, A>;
 | 
					    type Item = Event<C, A>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn next(&mut self) -> Option<Self::Item> {
 | 
					    fn next(&mut self) -> Option<Self::Item> {
 | 
				
			||||||
| 
						 | 
					@ -223,7 +195,12 @@ impl<C: Clone, A: Clone> Builder<C, A> {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub(super) fn finish(self) -> Tree<C, A> {
 | 
					    pub(super) fn finish(self) -> Tree<C, A> {
 | 
				
			||||||
        Tree(self.nodes.into_boxed_slice())
 | 
					        let head = self.nodes[NodeIndex::root().index()].next;
 | 
				
			||||||
 | 
					        Tree {
 | 
				
			||||||
 | 
					            nodes: self.nodes.into_boxed_slice().into(),
 | 
				
			||||||
 | 
					            branch: Vec::new(),
 | 
				
			||||||
 | 
					            head,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn add_node(&mut self, node: Node<C, A>) {
 | 
					    fn add_node(&mut self, node: Node<C, A>) {
 | 
				
			||||||
| 
						 | 
					@ -259,11 +236,11 @@ impl<C: std::fmt::Debug + Clone + 'static, A: std::fmt::Debug + Clone + 'static>
 | 
				
			||||||
    for Builder<C, A>
 | 
					    for Builder<C, A>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
					    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
				
			||||||
        self.clone().finish().root().fmt(f)
 | 
					        self.clone().finish().fmt(f)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<C: std::fmt::Debug + Clone, A: std::fmt::Debug + Clone> std::fmt::Debug for Branch<C, A> {
 | 
					impl<C: std::fmt::Debug + Clone, A: std::fmt::Debug + Clone> std::fmt::Debug for Tree<C, A> {
 | 
				
			||||||
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
					    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
				
			||||||
        const INDENT: &str = "  ";
 | 
					        const INDENT: &str = "  ";
 | 
				
			||||||
        let mut level = 0;
 | 
					        let mut level = 0;
 | 
				
			||||||
| 
						 | 
					@ -348,11 +325,11 @@ mod test {
 | 
				
			||||||
        b.exit();
 | 
					        b.exit();
 | 
				
			||||||
        b.enter(3, sp);
 | 
					        b.enter(3, sp);
 | 
				
			||||||
        b.atom(31, sp);
 | 
					        b.atom(31, sp);
 | 
				
			||||||
        let tree = b.finish();
 | 
					        b.exit();
 | 
				
			||||||
 | 
					        let mut tree = b.finish();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut root_branch = tree.root();
 | 
					 | 
				
			||||||
        assert_eq!(
 | 
					        assert_eq!(
 | 
				
			||||||
            (&mut root_branch).take(3).collect::<Vec<_>>(),
 | 
					            (&mut tree).take(3).collect::<Vec<_>>(),
 | 
				
			||||||
            &[
 | 
					            &[
 | 
				
			||||||
                Event {
 | 
					                Event {
 | 
				
			||||||
                    kind: EventKind::Enter(1),
 | 
					                    kind: EventKind::Enter(1),
 | 
				
			||||||
| 
						 | 
					@ -369,14 +346,14 @@ mod test {
 | 
				
			||||||
            ]
 | 
					            ]
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        assert_eq!(
 | 
					        assert_eq!(
 | 
				
			||||||
            root_branch.next(),
 | 
					            tree.next(),
 | 
				
			||||||
            Some(Event {
 | 
					            Some(Event {
 | 
				
			||||||
                kind: EventKind::Enter(2),
 | 
					                kind: EventKind::Enter(2),
 | 
				
			||||||
                span: sp
 | 
					                span: sp
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        assert_eq!(
 | 
					        assert_eq!(
 | 
				
			||||||
            root_branch.take_branch().collect::<Vec<_>>(),
 | 
					            tree.take_branch().collect::<Vec<_>>(),
 | 
				
			||||||
            &[
 | 
					            &[
 | 
				
			||||||
                Event {
 | 
					                Event {
 | 
				
			||||||
                    kind: EventKind::Enter(21),
 | 
					                    kind: EventKind::Enter(21),
 | 
				
			||||||
| 
						 | 
					@ -393,7 +370,7 @@ mod test {
 | 
				
			||||||
            ]
 | 
					            ]
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        assert_eq!(
 | 
					        assert_eq!(
 | 
				
			||||||
            root_branch.collect::<Vec<_>>(),
 | 
					            tree.collect::<Vec<_>>(),
 | 
				
			||||||
            &[
 | 
					            &[
 | 
				
			||||||
                Event {
 | 
					                Event {
 | 
				
			||||||
                    kind: EventKind::Enter(3),
 | 
					                    kind: EventKind::Enter(3),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue