xsd_schema/xpath/
arena.rs1use crate::xpath::ast::AstNode;
8
9pub type AstNodeId = u32;
14
15pub const NO_NODE: AstNodeId = u32::MAX;
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
20pub struct SourceSpan {
21 pub start: usize,
23 pub end: usize,
25}
26
27impl SourceSpan {
28 #[inline]
30 pub fn new(start: usize, end: usize) -> Self {
31 Self { start, end }
32 }
33
34 #[inline]
36 pub fn at(pos: usize) -> Self {
37 Self {
38 start: pos,
39 end: pos,
40 }
41 }
42
43 #[inline]
45 pub fn merge(self, other: Self) -> Self {
46 Self {
47 start: self.start.min(other.start),
48 end: self.end.max(other.end),
49 }
50 }
51
52 #[inline]
54 pub fn is_empty(&self) -> bool {
55 self.start >= self.end
56 }
57
58 #[inline]
60 pub fn len(&self) -> usize {
61 self.end.saturating_sub(self.start)
62 }
63}
64
65#[derive(Debug, Default, Clone)]
70pub struct AstArena {
71 nodes: Vec<AstNode>,
72}
73
74impl AstArena {
75 #[inline]
77 pub fn new() -> Self {
78 Self { nodes: Vec::new() }
79 }
80
81 #[inline]
83 pub fn with_capacity(capacity: usize) -> Self {
84 Self {
85 nodes: Vec::with_capacity(capacity),
86 }
87 }
88
89 #[inline]
91 pub fn add(&mut self, node: AstNode) -> AstNodeId {
92 let id = self.nodes.len() as AstNodeId;
93 self.nodes.push(node);
94 id
95 }
96
97 #[inline]
102 pub fn get(&self, id: AstNodeId) -> &AstNode {
103 &self.nodes[id as usize]
104 }
105
106 #[inline]
111 pub fn get_mut(&mut self, id: AstNodeId) -> &mut AstNode {
112 &mut self.nodes[id as usize]
113 }
114
115 #[inline]
117 pub fn try_get(&self, id: AstNodeId) -> Option<&AstNode> {
118 self.nodes.get(id as usize)
119 }
120
121 #[inline]
123 pub fn try_get_mut(&mut self, id: AstNodeId) -> Option<&mut AstNode> {
124 self.nodes.get_mut(id as usize)
125 }
126
127 #[inline]
129 pub fn len(&self) -> usize {
130 self.nodes.len()
131 }
132
133 #[inline]
135 pub fn is_empty(&self) -> bool {
136 self.nodes.is_empty()
137 }
138
139 #[inline]
141 pub fn clear(&mut self) {
142 self.nodes.clear();
143 }
144
145 #[inline]
147 pub fn iter(&self) -> impl Iterator<Item = (AstNodeId, &AstNode)> {
148 self.nodes
149 .iter()
150 .enumerate()
151 .map(|(i, n)| (i as AstNodeId, n))
152 }
153}
154
155#[cfg(test)]
156mod tests {
157 use super::*;
158 use crate::xpath::ast::{AstNode, ValueNode};
159
160 #[test]
161 fn test_source_span() {
162 let span = SourceSpan::new(10, 20);
163 assert_eq!(span.start, 10);
164 assert_eq!(span.end, 20);
165 assert_eq!(span.len(), 10);
166 assert!(!span.is_empty());
167
168 let empty = SourceSpan::at(5);
169 assert!(empty.is_empty());
170 assert_eq!(empty.len(), 0);
171 }
172
173 #[test]
174 fn test_span_merge() {
175 let a = SourceSpan::new(10, 20);
176 let b = SourceSpan::new(15, 30);
177 let merged = a.merge(b);
178 assert_eq!(merged.start, 10);
179 assert_eq!(merged.end, 30);
180 }
181
182 #[test]
183 fn test_arena_basic() {
184 let mut arena = AstArena::new();
185 assert!(arena.is_empty());
186
187 let id1 = arena.add(AstNode::Value(ValueNode::Empty));
188 let id2 = arena.add(AstNode::Value(ValueNode::Boolean(true)));
189
190 assert_eq!(arena.len(), 2);
191 assert_eq!(id1, 0);
192 assert_eq!(id2, 1);
193 }
194
195 #[test]
196 fn test_arena_get() {
197 let mut arena = AstArena::new();
198 let id = arena.add(AstNode::Value(ValueNode::String("test".to_string())));
199
200 match arena.get(id) {
201 AstNode::Value(ValueNode::String(s)) => assert_eq!(s, "test"),
202 _ => panic!("Unexpected node type"),
203 }
204 }
205
206 #[test]
207 fn test_arena_try_get() {
208 let arena = AstArena::new();
209 assert!(arena.try_get(0).is_none());
210 assert!(arena.try_get(100).is_none());
211 }
212
213 #[test]
214 fn test_arena_iter() {
215 let mut arena = AstArena::new();
216 arena.add(AstNode::Value(ValueNode::Empty));
217 arena.add(AstNode::Value(ValueNode::Boolean(true)));
218
219 let ids: Vec<_> = arena.iter().map(|(id, _)| id).collect();
220 assert_eq!(ids, vec![0, 1]);
221 }
222}