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::*;
|
||||
|
||||
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);
|
||||
};
|
||||
|
|
14
src/lib.rs
14
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(
|
||||
|
|
63
src/tree.rs
63
src/tree.rs
|
@ -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),
|
||||
|
|
Loading…
Reference in a new issue