use super::node_id::NodeId;
use super::node_kind::NodeKind;
use super::structure_node::StructureNode;
#[derive(Debug, Clone)]
pub struct StructureAst {
root: NodeId,
arena: Vec<Option<StructureNode>>,
next_id: u64,
}
impl StructureAst {
#[must_use]
pub fn new() -> Self {
let root_id = NodeId::from_raw(0);
let root_node = StructureNode::new(
root_id,
NodeKind::Sequence {
children: Vec::new(),
},
);
Self {
root: root_id,
arena: vec![Some(root_node)],
next_id: 1,
}
}
#[allow(clippy::cast_possible_truncation)] pub fn add_node(&mut self, kind: NodeKind) -> NodeId {
let id = NodeId::from_raw(self.next_id);
self.next_id += 1;
let node = StructureNode::new(id, kind);
let idx = id.value() as usize;
if idx >= self.arena.len() {
self.arena.resize_with(idx + 1, || None);
}
self.arena[idx] = Some(node);
id
}
#[must_use]
#[allow(clippy::cast_possible_truncation)] pub fn get(&self, id: NodeId) -> Option<&StructureNode> {
self.arena
.get(id.value() as usize)
.and_then(|slot| slot.as_ref())
}
#[allow(clippy::cast_possible_truncation)] pub fn get_mut(&mut self, id: NodeId) -> Option<&mut StructureNode> {
self.arena
.get_mut(id.value() as usize)
.and_then(|slot| slot.as_mut())
}
#[allow(clippy::cast_possible_truncation)] pub fn remove(&mut self, id: NodeId) -> Option<StructureNode> {
self.arena
.get_mut(id.value() as usize)
.and_then(Option::take)
}
#[must_use]
pub fn root(&self) -> NodeId {
self.root
}
pub fn set_root(&mut self, id: NodeId) {
self.root = id;
}
#[must_use]
pub fn contains(&self, id: NodeId) -> bool {
self.get(id).is_some()
}
#[must_use]
pub fn len(&self) -> usize {
self.arena.iter().filter(|s| s.is_some()).count()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn iter(&self) -> impl Iterator<Item = &StructureNode> {
self.arena.iter().filter_map(|s| s.as_ref())
}
#[must_use]
pub fn next_id(&self) -> u64 {
self.next_id
}
#[must_use]
pub fn arena_raw(&self) -> &[Option<StructureNode>] {
&self.arena
}
#[must_use]
pub fn from_raw_parts(root: NodeId, arena: Vec<Option<StructureNode>>, next_id: u64) -> Self {
Self {
root,
arena,
next_id,
}
}
}
impl Default for StructureAst {
fn default() -> Self {
Self::new()
}
}