use std::{fmt::Display, ops::Range}; pub enum Text { Span(Range), Static(&'static str), String(String), } impl Default for Text { fn default() -> Self { Self::Static("") } } impl Text { pub fn empty() -> Self { Self::default() } pub fn is_empty(&self) -> bool { match self { Self::Span(s) => s.is_empty(), Self::Static(s) => s.is_empty(), Self::String(s) => s.is_empty(), } } pub fn as_str<'a>(&'a self, text: &'a str) -> &'a str { match self { Self::Span(s) => &text[s.clone()], Self::Static(s) => s, Self::String(s) => s.as_str(), } } } #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct NodeRef(usize); #[derive(Default)] pub struct NodeStorage { tags: Vec, parents: Vec>, children: Vec>, siblings_prev: Vec>, siblings_next: Vec>, texts: Vec, } impl NodeStorage { pub fn nodes(&self) -> impl Iterator { (0..self.tags.len()).map(NodeRef) } pub fn new_node(&mut self, tag: u16) -> NodeRef { let node = NodeRef(self.tags.len()); self.tags.push(tag); self.parents.push(None); self.children.push(vec![]); self.siblings_prev.push(None); self.siblings_next.push(None); self.texts.push(Text::default()); node } pub fn tag(&self, node: NodeRef) -> u16 { self.tags[node.0] } pub fn parent(&self, node: NodeRef) -> Option { self.parents[node.0] } pub fn set_parent(&mut self, child: NodeRef, parent: NodeRef) { self.parents[child.0] = Some(parent); } pub fn children(&self, node: NodeRef) -> impl Iterator { self.children[node.0].iter().copied() } pub fn append_child(&mut self, parent: NodeRef, child: NodeRef) { self.set_parent(child, parent); let children = &mut self.children[parent.0]; let child_index = children.len(); children.push(child); if child_index > 0 { let prev_index = child_index - 1; let prev_sibling = children[prev_index]; self.set_sibling_next(prev_sibling, child); self.set_sibling_prev(child, prev_sibling); } } pub fn sibling_next(&mut self, node: NodeRef) -> Option { self.siblings_next[node.0] } pub fn set_sibling_next(&mut self, this: NodeRef, next: NodeRef) { self.siblings_next[this.0] = Some(next); } pub fn sibling_prev(&mut self, node: NodeRef) -> Option { self.siblings_prev[node.0] } pub fn set_sibling_prev(&mut self, this: NodeRef, prev: NodeRef) { self.siblings_prev[this.0] = Some(prev); } pub fn text(&self, node: NodeRef) -> &Text { &self.texts[node.0] } pub fn set_text(&mut self, node: NodeRef, text: Text) { self.texts[node.0] = text; } pub fn display_syntax<'a>( &'a self, text: &'a str, node: NodeRef, ) -> impl Display + 'a { struct DisplaySyntax<'a> { nodes: &'a NodeStorage, node: NodeRef, text: &'a str, } impl Display for DisplaySyntax<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let s = match self.nodes.text(self.node) { Text::Span(s) => &self.text[s.clone()], Text::Static(s) => s, Text::String(s) => s.as_str(), }; write!(f, "{s}")?; for child in self.nodes.children(self.node) { write!( f, "{}", self.nodes.display_syntax(self.text, child) )?; } Ok(()) } } DisplaySyntax { nodes: self, node, text, } } } impl NodeStorage { pub fn new() -> Self { Self::default() } }