diff --git a/src/block.rs b/src/block.rs index 0c4b97c..1dd8a34 100644 --- a/src/block.rs +++ b/src/block.rs @@ -12,7 +12,6 @@ use Leaf::*; use ListType::*; pub type Tree = tree::Tree; -pub type Branch = tree::Branch; pub type TreeBuilder = tree::Builder; #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -523,7 +522,7 @@ mod test { macro_rules! test_parse { ($src:expr $(,$($event:expr),* $(,)?)?) => { let t = super::TreeParser::new($src).parse(); - let actual = t.root().map(|ev| (ev.kind, ev.span.of($src))).collect::>(); + let actual = t.map(|ev| (ev.kind, ev.span.of($src))).collect::>(); let expected = &[$($($event),*,)?]; assert_eq!(actual, expected, "\n\n{}\n\n", $src); }; diff --git a/src/lib.rs b/src/lib.rs index 06c6975..3547473 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -263,14 +263,11 @@ impl<'s> Container<'s> { pub struct Parser<'s> { 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: std::collections::HashMap<&'s str, CowStr<'s>>, /// Block tree cursor. - tree: block::Branch, + tree: block::Tree, /// Spans to the inlines in the block currently being parsed. inlines: span::InlineSpans<'s>, /// 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: Vec<&'s str>, /// 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. footnote_index: usize, /// Currently within a footnote. @@ -292,7 +289,7 @@ impl<'s> Parser<'s> { let tree = block::parse(src); let link_definitions = { - let mut branch = tree.root(); + let mut branch = tree.clone(); let mut defs = std::collections::HashMap::new(); while let Some(e) = branch.next() { if let tree::EventKind::Enter(block::Node::Leaf(block::Leaf::LinkDefinition)) = @@ -310,11 +307,10 @@ impl<'s> Parser<'s> { defs }; - let branch = tree.root(); + let branch = tree.clone(); Self { src, - _tree_data: tree, link_definitions, tree: branch, footnote_references: Vec::new(), @@ -523,7 +519,7 @@ impl<'s> Parser<'s> { self.tree = self .footnotes .remove(tag) - .unwrap_or_else(block::Branch::empty); + .unwrap_or_else(block::Tree::empty); self.footnote_active = true; Some(Event::Start( diff --git a/src/tree.rs b/src/tree.rs index 50b6628..f76a876 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -14,45 +14,17 @@ pub struct Event { pub span: Span, } -pub struct Tree(Box<[Node]>); - #[derive(Clone)] -pub struct Inlines<'t, C, A> { - iter: std::slice::Iter<'t, Node>, -} - -impl<'t, C, A> Iterator for Inlines<'t, C, A> { - type Item = Span; - - fn next(&mut self) -> Option { - self.iter.next().map(|n| n.span) - } -} - -impl Tree { - pub fn root(&self) -> Branch { - let head = self.0[NodeIndex::root().index()].next; - // SAFETY: tree must outlive the branch - let nodes = unsafe { std::mem::transmute::<&[Node], &'static [Node]>(&self.0) }; - Branch { - nodes, - branch: Vec::new(), - head, - } - } -} - -#[derive(Clone)] -pub struct Branch { - nodes: &'static [Node], +pub struct Tree { + nodes: std::rc::Rc<[Node]>, branch: Vec, head: Option, } -impl Branch { +impl Tree { pub fn empty() -> Self { Self { - nodes: &[], + nodes: vec![].into_boxed_slice().into(), branch: Vec::new(), head: None, } @@ -78,7 +50,7 @@ impl Branch { self.head = n.next; } Self { - nodes: self.nodes, + nodes: self.nodes.clone(), branch: Vec::new(), head, } @@ -99,7 +71,7 @@ impl Branch { } } -impl Iterator for Branch { +impl Iterator for Tree { type Item = Event; fn next(&mut self) -> Option { @@ -223,7 +195,12 @@ impl Builder { } pub(super) fn finish(self) -> Tree { - 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) { @@ -259,11 +236,11 @@ impl for Builder { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.clone().finish().root().fmt(f) + self.clone().finish().fmt(f) } } -impl std::fmt::Debug for Branch { +impl std::fmt::Debug for Tree { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { const INDENT: &str = " "; let mut level = 0; @@ -348,11 +325,11 @@ mod test { b.exit(); b.enter(3, sp); b.atom(31, sp); - let tree = b.finish(); + b.exit(); + let mut tree = b.finish(); - let mut root_branch = tree.root(); assert_eq!( - (&mut root_branch).take(3).collect::>(), + (&mut tree).take(3).collect::>(), &[ Event { kind: EventKind::Enter(1), @@ -369,14 +346,14 @@ mod test { ] ); assert_eq!( - root_branch.next(), + tree.next(), Some(Event { kind: EventKind::Enter(2), span: sp }) ); assert_eq!( - root_branch.take_branch().collect::>(), + tree.take_branch().collect::>(), &[ Event { kind: EventKind::Enter(21), @@ -393,7 +370,7 @@ mod test { ] ); assert_eq!( - root_branch.collect::>(), + tree.collect::>(), &[ Event { kind: EventKind::Enter(3),