fixup! tree: add tree branch reference

This commit is contained in:
Noah Hellman 2023-01-21 13:36:21 +01:00
parent a62eb3e1d8
commit 5e8c683050
3 changed files with 26 additions and 54 deletions

View file

@ -12,7 +12,6 @@ use Leaf::*;
use ListType::*;
pub type Tree = tree::Tree<Node, Atom>;
pub type Branch = tree::Branch<Node, Atom>;
pub type TreeBuilder = tree::Builder<Node, Atom>;
#[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::<Vec<_>>();
let actual = t.map(|ev| (ev.kind, ev.span.of($src))).collect::<Vec<_>>();
let expected = &[$($($event),*,)?];
assert_eq!(actual, expected, "\n\n{}\n\n", $src);
};

View file

@ -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(

View file

@ -14,45 +14,17 @@ pub struct Event<C, A> {
pub span: Span,
}
pub struct Tree<C, A>(Box<[Node<C, A>]>);
#[derive(Clone)]
pub struct Inlines<'t, C, A> {
iter: std::slice::Iter<'t, 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>],
pub struct Tree<C: 'static, A: 'static> {
nodes: std::rc::Rc<[Node<C, A>]>,
branch: Vec<NodeIndex>,
head: Option<NodeIndex>,
}
impl<C, A> Branch<C, A> {
impl<C: Clone, A: Clone> Tree<C, A> {
pub fn empty() -> Self {
Self {
nodes: &[],
nodes: vec![].into_boxed_slice().into(),
branch: Vec::new(),
head: None,
}
@ -78,7 +50,7 @@ impl<C, A> Branch<C, A> {
self.head = n.next;
}
Self {
nodes: self.nodes,
nodes: self.nodes.clone(),
branch: Vec::new(),
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>;
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> {
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>) {
@ -259,11 +236,11 @@ impl<C: std::fmt::Debug + Clone + 'static, A: std::fmt::Debug + Clone + 'static>
for Builder<C, A>
{
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 {
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::<Vec<_>>(),
(&mut tree).take(3).collect::<Vec<_>>(),
&[
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::<Vec<_>>(),
tree.take_branch().collect::<Vec<_>>(),
&[
Event {
kind: EventKind::Enter(21),
@ -393,7 +370,7 @@ mod test {
]
);
assert_eq!(
root_branch.collect::<Vec<_>>(),
tree.collect::<Vec<_>>(),
&[
Event {
kind: EventKind::Enter(3),