cp_ast_core/structure/
structure_ast.rs1use super::node_id::NodeId;
2use super::node_kind::NodeKind;
3use super::structure_node::StructureNode;
4
5#[derive(Debug, Clone)]
10pub struct StructureAst {
11 root: NodeId,
12 arena: Vec<Option<StructureNode>>,
13 next_id: u64,
14}
15
16impl StructureAst {
17 #[must_use]
19 pub fn new() -> Self {
20 let root_id = NodeId::from_raw(0);
21 let root_node = StructureNode::new(
22 root_id,
23 NodeKind::Sequence {
24 children: Vec::new(),
25 },
26 );
27 Self {
28 root: root_id,
29 arena: vec![Some(root_node)],
30 next_id: 1,
31 }
32 }
33
34 #[allow(clippy::cast_possible_truncation)] pub fn add_node(&mut self, kind: NodeKind) -> NodeId {
37 let id = NodeId::from_raw(self.next_id);
38 self.next_id += 1;
39 let node = StructureNode::new(id, kind);
40 let idx = id.value() as usize;
41 if idx >= self.arena.len() {
42 self.arena.resize_with(idx + 1, || None);
43 }
44 self.arena[idx] = Some(node);
45 id
46 }
47
48 #[must_use]
50 #[allow(clippy::cast_possible_truncation)] pub fn get(&self, id: NodeId) -> Option<&StructureNode> {
52 self.arena
53 .get(id.value() as usize)
54 .and_then(|slot| slot.as_ref())
55 }
56
57 #[allow(clippy::cast_possible_truncation)] pub fn get_mut(&mut self, id: NodeId) -> Option<&mut StructureNode> {
60 self.arena
61 .get_mut(id.value() as usize)
62 .and_then(|slot| slot.as_mut())
63 }
64
65 #[allow(clippy::cast_possible_truncation)] pub fn remove(&mut self, id: NodeId) -> Option<StructureNode> {
68 self.arena
69 .get_mut(id.value() as usize)
70 .and_then(Option::take)
71 }
72
73 #[must_use]
75 pub fn root(&self) -> NodeId {
76 self.root
77 }
78
79 pub fn set_root(&mut self, id: NodeId) {
81 self.root = id;
82 }
83
84 #[must_use]
86 pub fn contains(&self, id: NodeId) -> bool {
87 self.get(id).is_some()
88 }
89
90 #[must_use]
92 pub fn len(&self) -> usize {
93 self.arena.iter().filter(|s| s.is_some()).count()
94 }
95
96 #[must_use]
98 pub fn is_empty(&self) -> bool {
99 self.len() == 0
100 }
101
102 pub fn iter(&self) -> impl Iterator<Item = &StructureNode> {
104 self.arena.iter().filter_map(|s| s.as_ref())
105 }
106
107 #[must_use]
109 pub fn next_id(&self) -> u64 {
110 self.next_id
111 }
112
113 #[must_use]
117 pub fn arena_raw(&self) -> &[Option<StructureNode>] {
118 &self.arena
119 }
120
121 #[must_use]
126 pub fn from_raw_parts(root: NodeId, arena: Vec<Option<StructureNode>>, next_id: u64) -> Self {
127 Self {
128 root,
129 arena,
130 next_id,
131 }
132 }
133}
134
135impl Default for StructureAst {
136 fn default() -> Self {
137 Self::new()
138 }
139}