1use serde_repr::Deserialize_repr;
2
3use crate::page::Link;
4
5#[derive(Clone, PartialEq, Eq)]
6pub struct Document {
7 pub nodes: Vec<Raw>,
8}
9
10impl std::fmt::Debug for Document {
11 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12 write!(f, "nodes: {}", self.nodes.len())
13 }
14}
15
16impl Document {
17 pub fn nth(&self, n: usize) -> Option<Node> {
18 Node::new(self, n)
19 }
20}
21
22#[derive(Clone, Debug, PartialEq, Eq, Deserialize_repr)]
23#[repr(usize)]
24pub enum HeaderKind {
25 Main = 1,
26 Sub = 2,
27 Section = 3,
28 Subsection = 4,
29 Minor = 5,
30 Detail = 6,
31}
32
33#[derive(Default, Clone, Debug, PartialEq, Eq)]
34pub enum Data {
35 Section {
36 id: usize,
37 },
38 Header {
39 id: String,
40 kind: HeaderKind,
41 },
42 Text {
43 contents: String,
44 },
45 Division,
46 Paragraph,
47 Span,
48 Reflink,
49 Hatnote,
50 RedirectMessage,
51 Disambiguation,
52 Blockquote,
53
54 OrderedList,
55 UnorderedList,
56 ListItem,
57
58 DescriptionList,
59 DescriptionListTerm,
60 DerscriptionListDescription,
61
62 Bold,
63 Italic,
64
65 Linebreak,
66
67 Link(Link),
68 #[default]
69 Unknown,
70
71 Unsupported(UnsupportedElement),
72 UnsupportedInline(UnsupportedElement),
73}
74
75#[derive(Clone, Debug, PartialEq, Eq)]
76pub enum UnsupportedElement {
77 Table,
78 Image,
79 Figure,
80 MathElement,
81 PreformattedText,
82}
83
84#[derive(Clone, Debug, PartialEq, Eq)]
85pub struct Raw {
86 pub index: usize,
87 pub parent: Option<usize>,
88 pub prev: Option<usize>,
89 pub next: Option<usize>,
90 pub first_child: Option<usize>,
91 pub last_child: Option<usize>,
92 pub data: Data,
93}
94
95#[derive(Copy, Clone, Debug, PartialEq, Eq)]
96pub struct Node<'a> {
97 document: &'a Document,
98 index: usize,
99}
100
101impl<'a> Node<'a> {
102 pub fn new(document: &'a Document, index: usize) -> Option<Node<'a>> {
103 if index < document.nodes.len() {
104 Some(Node { document, index })
105 } else {
106 None
107 }
108 }
109
110 pub fn index(&self) -> usize {
111 self.index
112 }
113
114 pub fn raw(&self) -> &'a Raw {
115 &self.document.nodes[self.index]
116 }
117
118 pub fn data(&self) -> &'a Data {
119 &self.raw().data
120 }
121
122 pub fn parent(&self) -> Option<Node<'a>> {
123 self.raw()
124 .parent
125 .map(|index| self.document.nth(index).unwrap())
126 }
127
128 pub fn prev(&self) -> Option<Node<'a>> {
129 self.raw()
130 .prev
131 .map(|index| self.document.nth(index).unwrap())
132 }
133
134 pub fn next(&self) -> Option<Node<'a>> {
135 self.raw()
136 .next
137 .map(|index| self.document.nth(index).unwrap())
138 }
139
140 pub fn first_child(&self) -> Option<Node<'a>> {
141 self.raw()
142 .first_child
143 .map(|index| self.document.nth(index).unwrap())
144 }
145
146 pub fn last_child(&self) -> Option<Node<'a>> {
147 self.raw()
148 .last_child
149 .map(|index| self.document.nth(index).unwrap())
150 }
151
152 pub fn descendants(&self) -> Descendants<'a> {
153 Descendants {
154 start: *self,
155 current: *self,
156 done: false,
157 }
158 }
159
160 pub fn children(&self) -> Children<'a> {
161 Children {
162 next: self.first_child(),
163 }
164 }
165}
166
167#[derive(Clone, Debug)]
168pub struct Descendants<'a> {
169 start: Node<'a>,
170 current: Node<'a>,
171 done: bool,
172}
173
174impl<'a> Iterator for Descendants<'a> {
175 type Item = Node<'a>;
176
177 fn next(&mut self) -> Option<Node<'a>> {
178 if self.done {
179 return None;
180 }
181
182 if self.start.index() == self.current.index() {
184 if let Some(first_child) = self.current.first_child() {
185 self.current = first_child;
186 } else {
187 self.done = true;
188 return None;
189 }
190 } else {
191 if let Some(first_child) = self.current.first_child() {
193 self.current = first_child;
194 } else if let Some(next) = self.current.next() {
195 self.current = next;
196 } else {
197 loop {
198 let parent = self.current.parent().unwrap();
200 if parent.index() == self.start.index() {
201 self.done = true;
202 return None;
203 }
204 if let Some(next) = parent.next() {
205 self.current = next;
206 break;
207 }
208 self.current = parent;
209 }
210 }
211 }
212
213 Some(self.current)
214 }
215}
216
217pub struct Children<'a> {
218 next: Option<Node<'a>>,
219}
220
221impl<'a> Iterator for Children<'a> {
222 type Item = Node<'a>;
223 fn next(&mut self) -> Option<Node<'a>> {
224 if let Some(next) = self.next {
225 self.next = next.next();
226 Some(next)
227 } else {
228 None
229 }
230 }
231}