summaryrefslogtreecommitdiffstats
path: root/src/doxygen.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/doxygen.rs')
-rw-r--r--src/doxygen.rs454
1 files changed, 0 insertions, 454 deletions
diff --git a/src/doxygen.rs b/src/doxygen.rs
deleted file mode 100644
index 8d2267d..0000000
--- a/src/doxygen.rs
+++ /dev/null
@@ -1,454 +0,0 @@
1/// A 'recursive descent' parser for Doxygen XML files
2mod builders;
3
4use xml::{
5 attribute::OwnedAttribute,
6 reader::{EventReader, ParserConfig, XmlEvent},
7};
8
9use std::collections::HashMap;
10use std::io::Read;
11
12// === Types ===
13
14#[derive(Debug, Clone)]
15pub(crate) enum DoxygenType {
16 NameSpace(NameSpace),
17 Class(Class),
18 Unhandled,
19}
20
21#[derive(Debug, Clone)]
22pub(crate) struct NameSpace {
23 pub(crate) name: String,
24 pub(crate) members: Vec<String>,
25 pub(crate) brief_description: Description,
26 pub(crate) detailed_description: Description,
27}
28
29#[derive(Debug, Clone)]
30pub(crate) struct FunctionArgument {
31 pub(crate) name: String,
32 pub(crate) r#type: String,
33 pub(crate) default_value: Option<String>,
34}
35
36#[derive(Debug, Clone)]
37pub(crate) enum Member {
38 Variable {
39 name: String,
40 r#type: String,
41 },
42 // What
43 /*
44 Enum {
45
46 }
47 */
48 Function {
49 name: String,
50 args: Vec<FunctionArgument>,
51 return_type: String,
52 },
53 Unhandled,
54}
55
56#[derive(Debug, Clone)]
57pub(crate) struct Class {
58 pub(crate) name: String,
59 pub(crate) inners: Vec<(String, String)>,
60 pub(crate) sections: HashMap<String, Vec<Member>>,
61 pub(crate) brief_description: Description,
62 pub(crate) detailed_description: Description,
63}
64
65// === Description ===
66
67#[derive(Debug, Clone)]
68pub(crate) struct Description {
69 pub(crate) inner: Vec<DescriptionNode>,
70}
71
72impl Description {
73 fn new() -> Self {
74 Self { inner: Vec::new() }
75 }
76}
77
78#[derive(Debug, Clone)]
79pub(crate) enum DescriptionNode {
80 Text(String),
81 Title(String),
82 Para(Paragraph),
83 Sect1(String),
84 Internal(String),
85}
86
87#[derive(Debug, Clone)]
88pub(crate) struct Paragraph {
89 pub(crate) inner: Vec<ParagraphNode>,
90}
91
92#[derive(Debug, Clone)]
93pub(crate) enum ParagraphNode {
94 Text(String),
95 Ref(Ref),
96}
97
98#[derive(Debug, Clone)]
99pub(crate) struct Ref {
100 pub(crate) id: String,
101 pub(crate) kind: RefKind,
102 pub(crate) text: String,
103}
104
105#[derive(Debug, Clone)]
106pub(crate) enum RefKind {
107 Compound,
108 Member,
109}
110
111#[derive(Debug, Clone)]
112enum DoxygenTypeKind {
113 NameSpace,
114 Unhandled,
115}
116
117trait TypeBuilder {
118 //const KIND: DoxygenTypeKind;
119
120 fn build(self: Box<Self>) -> DoxygenType;
121
122 fn name(&mut self, value: String);
123 fn brief_description(&mut self, description: Description);
124 fn detailed_description(&mut self, description: Description);
125
126 fn add_inner(&mut self, name: String, kind: String);
127 fn add_member(&mut self, section: String, member: Member);
128}
129
130trait FromXML {
131 fn from_xml(attributes: Vec<OwnedAttribute>, event_reader: &mut EventReader<impl Read>)
132 -> Self;
133}
134
135impl FromXML for Description {
136 fn from_xml(
137 _attributes: Vec<OwnedAttribute>,
138 mut event_reader: &mut EventReader<impl Read>,
139 ) -> Self {
140 let mut inner = Vec::new();
141
142 while let Ok(event) = event_reader.next() {
143 match event {
144 XmlEvent::Characters(text) => inner.push(DescriptionNode::Text(text)),
145 XmlEvent::StartElement {
146 name, attributes, ..
147 } => inner.push(match name.local_name.as_str() {
148 "para" => {
149 DescriptionNode::Para(Paragraph::from_xml(attributes, &mut event_reader))
150 }
151 "title" => DescriptionNode::Title(event_simple(&mut event_reader)),
152 "sect1" => DescriptionNode::Sect1(event_simple(&mut event_reader)),
153 "internal" => DescriptionNode::Internal(event_simple(&mut event_reader)),
154 other => {
155 warn!("Description element not supported: {}", other);
156 continue;
157 }
158 }),
159 XmlEvent::EndElement { .. } => break,
160 other => {
161 warn!("Description event not supported: {:?}", other);
162 }
163 }
164 }
165
166 Self { inner }
167 }
168}
169
170impl FromXML for Paragraph {
171 fn from_xml(
172 _attributes: Vec<OwnedAttribute>,
173 mut event_reader: &mut EventReader<impl Read>,
174 ) -> Self {
175 let mut inner = Vec::new();
176
177 while let Ok(event) = event_reader.next() {
178 match event {
179 XmlEvent::Characters(text) => inner.push(ParagraphNode::Text(text)),
180 XmlEvent::StartElement {
181 name, attributes, ..
182 } => inner.push(match name.local_name.as_str() {
183 "ref" => ParagraphNode::Ref(Ref::from_xml(attributes, &mut event_reader)),
184 other => {
185 warn!("Paragraph element not supported: {}", other);
186 continue;
187 }
188 }),
189 XmlEvent::EndElement { .. } => break,
190 other => {
191 warn!("Paragraph event not supported: {:?}", other);
192 }
193 }
194 }
195
196 Self { inner }
197 }
198}
199
200impl FromXML for Ref {
201 fn from_xml(
202 attributes: Vec<OwnedAttribute>,
203 mut event_reader: &mut EventReader<impl Read>,
204 ) -> Self {
205 let mut id = None;
206 let mut kind = None;
207
208 for attr in attributes.into_iter() {
209 match attr.name.local_name.as_str() {
210 "refid" => id = Some(attr.value),
211 "kindref" => {
212 kind = Some(match attr.value.as_str() {
213 "compound" => RefKind::Compound,
214 "member" => RefKind::Member,
215 other => {
216 warn!("Ref kind not supported: {}", other);
217 RefKind::Compound
218 }
219 });
220 }
221 other => {
222 warn!("Ref element not supported: {}", other);
223 }
224 }
225 }
226
227 let text = event_simple(&mut event_reader);
228
229 Ref {
230 id: id.unwrap(),
231 kind: kind.unwrap(),
232 text,
233 }
234 }
235}
236
237/// Parse a type from a XML Doxygen file
238pub(crate) fn parse_type(reader: impl Read) -> Vec<DoxygenType> {
239 let mut event_reader = EventReader::new(reader);
240
241 match event_reader.next().unwrap() {
242 XmlEvent::StartDocument { .. } => (),
243 _ => panic!("XML file does not begin with document"),
244 }
245
246 match event_reader.next().unwrap() {
247 XmlEvent::StartElement { name, .. } => {
248 if name.local_name != "doxygen" {
249 panic!("XML file does not start with a 'doxygen' element");
250 }
251 }
252 _ => panic!("XML file does not start with a 'doxygen' element"),
253 }
254
255 let mut result = Vec::new();
256
257 while let Ok(event) = event_reader.next() {
258 match dbg!(event) {
259 XmlEvent::StartElement {
260 name, attributes, ..
261 } => {
262 if name.local_name != "compounddef" {
263 panic!("'doxygen' is not a sequence of 'compounddef' elements");
264 }
265
266 result.push(event_compounddef(attributes, &mut event_reader));
267 }
268 XmlEvent::Whitespace(_) => (),
269 XmlEvent::EndElement { .. } => break,
270 _ => panic!("'doxygen' is not a sequence of 'compounddef' elements"),
271 }
272 }
273
274 // Unnecessarily strict?
275 match event_reader.next().unwrap() {
276 XmlEvent::EndDocument => (),
277 _ => panic!("XML file does not end after 'doxygen' element"),
278 }
279
280 dbg!(result)
281}
282
283fn event_compounddef(
284 attributes: Vec<OwnedAttribute>,
285 mut event_reader: &mut EventReader<impl Read>,
286) -> DoxygenType {
287 let kind = attributes
288 .into_iter()
289 .find_map(|attr| {
290 if attr.name.local_name == "kind" {
291 Some(attr.value)
292 } else {
293 None
294 }
295 })
296 .unwrap();
297
298 let mut builder = builders::builder_for(kind);
299
300 while let Ok(event) = event_reader.next() {
301 match dbg!(event) {
302 XmlEvent::StartElement {
303 name, attributes, ..
304 } => match name.local_name.as_str() {
305 "compoundname" => {
306 let name = event_simple(&mut event_reader);
307 builder.name(name);
308 }
309 "briefdescription" => {
310 let brief_description = Description::from_xml(attributes, &mut event_reader);
311 builder.brief_description(brief_description);
312 }
313 "detaileddescription" => {
314 let detailed_description = Description::from_xml(attributes, &mut event_reader);
315 builder.detailed_description(detailed_description);
316 }
317 "location" => {
318 event_simple(&mut event_reader);
319 debug!("Do something?");
320 }
321 "sectiondef" => {
322 event_section(&mut builder, &mut event_reader);
323 }
324 other_name if is_inner_type(other_name) => {
325 let inner = event_simple(&mut event_reader);
326 builder.add_inner(inner, other_name.to_string());
327 }
328 _other_name => {
329 event_ignore(&mut event_reader);
330 }
331 },
332 XmlEvent::Whitespace(_) => (),
333 XmlEvent::EndElement { .. } => break,
334 _ => panic!("Unhandled XML event"),
335 }
336 }
337
338 builder.build()
339}
340
341/// Returns true if the given XML Element is a reference to another inner type.
342///
343/// Corresponds to the "refType" XSD type in `compound.xsd`
344fn is_inner_type(element_name: &str) -> bool {
345 match element_name {
346 "innerdir" | "innerfile" | "innerclass" | "innernamespace" | "innerpage" | "innergroup" => {
347 true
348 }
349 _ => false,
350 }
351}
352
353/// Get the text inside a simple, non recursive XML tag
354fn event_simple(event_reader: &mut EventReader<impl Read>) -> String {
355 let result;
356
357 match dbg!(event_reader.next().unwrap()) {
358 XmlEvent::Characters(tmp_result) => {
359 result = tmp_result;
360 }
361 XmlEvent::EndElement { .. } => return "".to_string(),
362 _ => panic!("Simple XML event is not so simple"),
363 }
364
365 match dbg!(event_reader.next().unwrap()) {
366 XmlEvent::EndElement { .. } => (),
367 _ => panic!("Simple XML event is not so simple"),
368 }
369
370 result
371}
372
373fn event_ignore(mut event_reader: &mut EventReader<impl Read>) {
374 loop {
375 let event = event_reader.next().unwrap();
376 match dbg!(event) {
377 XmlEvent::StartElement { .. } => event_ignore(&mut event_reader),
378 XmlEvent::EndElement { .. } => break,
379 _ => (),
380 }
381 }
382}
383
384fn event_section(
385 mut builder: &mut Box<dyn TypeBuilder>,
386 mut event_reader: &mut EventReader<impl Read>,
387) {
388 loop {
389 let event = event_reader.next().unwrap();
390 match dbg!(event) {
391 XmlEvent::StartElement {
392 name, attributes, ..
393 } => match name.local_name.as_str() {
394 "memberdef" => {
395 let member = event_member(attributes, &mut event_reader);
396 builder.add_member("bla".to_owned(), member);
397 }
398 _ => panic!("Unhandled thing"),
399 },
400
401 XmlEvent::Whitespace(_) => (),
402 XmlEvent::EndElement { .. } => break,
403 _ => panic!("Unknown section XML event"),
404 }
405 }
406}
407
408fn event_member(
409 attributes: Vec<OwnedAttribute>,
410 mut event_reader: &mut EventReader<impl Read>,
411) -> Member {
412 let kind = attributes
413 .into_iter()
414 .find_map(|attr| {
415 if attr.name.local_name == "kind" {
416 Some(attr.value)
417 } else {
418 None
419 }
420 })
421 .unwrap();
422
423 match kind.as_str() {
424 "variable" => event_member_variable(&mut event_reader),
425 _ => {
426 event_ignore(&mut event_reader);
427 Member::Unhandled
428 }
429 }
430}
431
432fn event_member_variable(mut event_reader: &mut EventReader<impl Read>) -> Member {
433 let mut member_name = None;
434 let mut r#type = None;
435
436 loop {
437 let event = event_reader.next().unwrap();
438 match dbg!(event) {
439 XmlEvent::StartElement { name, .. } => match name.local_name.as_str() {
440 "name" => member_name = Some(event_simple(&mut event_reader)),
441 "definition" => r#type = Some(event_simple(&mut event_reader)),
442 _ => event_ignore(&mut event_reader),
443 },
444 XmlEvent::Whitespace(_) => (),
445 XmlEvent::EndElement { .. } => break,
446 _ => panic!("Unknown member XML event"),
447 }
448 }
449
450 Member::Variable {
451 name: member_name.unwrap(),
452 r#type: r#type.unwrap(),
453 }
454}