Skip to main content

om_context/output/
xml.rs

1use super::{CatOutput, FileOutput, TreeOutput};
2use quick_xml::events::{BytesCData, BytesDecl, BytesEnd, BytesStart, BytesText, Event};
3use quick_xml::Writer;
4use std::error::Error;
5use std::io::Cursor;
6
7pub fn output_tree(data: &TreeOutput) -> Result<(), Box<dyn Error>> {
8    let mut writer = Writer::new_with_indent(Cursor::new(Vec::new()), b' ', 2);
9
10    writer.write_event(Event::Decl(BytesDecl::new("1.0", Some("UTF-8"), None)))?;
11
12    let codebase = BytesStart::new("codebase");
13    writer.write_event(Event::Start(codebase.borrow()))?;
14
15    write_element(&mut writer, "project", &data.project)?;
16
17    let files = BytesStart::new("files");
18    writer.write_event(Event::Start(files.borrow()))?;
19
20    for file in &data.files {
21        write_file_element(&mut writer, file)?;
22    }
23
24    writer.write_event(Event::End(BytesEnd::new("files")))?;
25    writer.write_event(Event::End(BytesEnd::new("codebase")))?;
26
27    let result = writer.into_inner().into_inner();
28    println!("{}", String::from_utf8(result)?);
29    Ok(())
30}
31
32pub fn output_cat(data: &CatOutput) -> Result<(), Box<dyn Error>> {
33    let mut writer = Writer::new_with_indent(Cursor::new(Vec::new()), b' ', 2);
34
35    writer.write_event(Event::Decl(BytesDecl::new("1.0", Some("UTF-8"), None)))?;
36
37    let codebase = BytesStart::new("codebase");
38    writer.write_event(Event::Start(codebase.borrow()))?;
39
40    write_element(&mut writer, "project", &data.project)?;
41
42    if let Some(ref session) = data.session {
43        write_element(&mut writer, "session", session)?;
44    }
45
46    write_element(&mut writer, "files_shown", &data.files_shown.to_string())?;
47    write_element(
48        &mut writer,
49        "skipped_binary",
50        &data.skipped_binary.to_string(),
51    )?;
52    write_element(
53        &mut writer,
54        "skipped_session",
55        &data.skipped_session.to_string(),
56    )?;
57    write_element(&mut writer, "total_lines", &data.total_lines.to_string())?;
58
59    let files = BytesStart::new("files");
60    writer.write_event(Event::Start(files.borrow()))?;
61
62    for file in &data.files {
63        write_file_element(&mut writer, file)?;
64    }
65
66    writer.write_event(Event::End(BytesEnd::new("files")))?;
67    writer.write_event(Event::End(BytesEnd::new("codebase")))?;
68
69    let result = writer.into_inner().into_inner();
70    println!("{}", String::from_utf8(result)?);
71    Ok(())
72}
73
74fn write_file_element<W: std::io::Write>(
75    writer: &mut Writer<W>,
76    file: &FileOutput,
77) -> Result<(), Box<dyn Error>> {
78    let mut elem = BytesStart::new("file");
79    elem.push_attribute(("path", file.path.as_str()));
80    elem.push_attribute(("score", file.score.to_string().as_str()));
81    elem.push_attribute(("lines", file.lines.to_string().as_str()));
82
83    if let Some(tokens) = file.tokens {
84        elem.push_attribute(("tokens", tokens.to_string().as_str()));
85    }
86
87    if let Some(ref content) = file.content {
88        writer.write_event(Event::Start(elem.borrow()))?;
89
90        let content_elem = BytesStart::new("content");
91        writer.write_event(Event::Start(content_elem.borrow()))?;
92        writer.write_event(Event::CData(BytesCData::new(content)))?;
93        writer.write_event(Event::End(BytesEnd::new("content")))?;
94
95        writer.write_event(Event::End(BytesEnd::new("file")))?;
96    } else {
97        writer.write_event(Event::Empty(elem))?;
98    }
99
100    Ok(())
101}
102
103fn write_element<W: std::io::Write>(
104    writer: &mut Writer<W>,
105    name: &str,
106    content: &str,
107) -> Result<(), Box<dyn Error>> {
108    let elem = BytesStart::new(name);
109    writer.write_event(Event::Start(elem.borrow()))?;
110    writer.write_event(Event::Text(BytesText::new(content)))?;
111    writer.write_event(Event::End(BytesEnd::new(name)))?;
112    Ok(())
113}