aboutsummaryrefslogtreecommitdiff
path: root/minirust.rs
diff options
context:
space:
mode:
Diffstat (limited to 'minirust.rs')
-rw-r--r--minirust.rs68
1 files changed, 68 insertions, 0 deletions
diff --git a/minirust.rs b/minirust.rs
new file mode 100644
index 000000000..d92c03bea
--- /dev/null
+++ b/minirust.rs
@@ -0,0 +1,68 @@
1pub struct NodeKind(u16);
2
3pub struct File {
4 text: String,
5 nodes: Vec<NodeData>,
6}
7
8struct NodeData {
9 kind: NodeKind,
10 range: (u32, u32),
11 parent: Option<u32>,
12 first_child: Option<u32>,
13 next_sibling: Option<u32>,
14}
15
16#[derive(Clone, Copy)]
17pub struct Node<'f> {
18 file: &'f File,
19 idx: u32,
20}
21
22pub struct Children<'f> {
23 next: Option<Node<'f>>,
24}
25
26impl File {
27 pub fn root<'f>(&'f self) -> Node<'f> {
28 assert!(!self.nodes.is_empty());
29 Node { file: self, idx: 0 }
30 }
31}
32
33impl<'f> Node<'f> {
34 pub fn kind(&self) -> NodeKind {
35 self.data().kind
36 }
37
38 pub fn text(&self) -> &'f str {
39 let (start, end) = self.data().range;
40 &self.file.text[start as usize..end as usize]
41 }
42
43 pub fn parent(&self) -> Option<Node<'f>> {
44 self.as_node(self.data().parent)
45 }
46
47 pub fn children(&self) -> Children<'f> {
48 Children { next: self.as_node(self.data().first_child) }
49 }
50
51 fn data(&self) -> &'f NodeData {
52 &self.file.nodes[self.idx as usize]
53 }
54
55 fn as_node(&self, idx: Option<u32>) -> Option<Node<'f>> {
56 idx.map(|idx| Node { file: self.file, idx })
57 }
58}
59
60impl<'f> Iterator for Children<'f> {
61 type Item = Node<'f>;
62
63 fn next(&mut self) -> Option<Node<'f>> {
64 let next = self.next;
65 self.next = next.and_then(|node| node.as_node(node.data().next_sibling));
66 next
67 }
68}