context_creator/formatters/
xml.rs1use super::{DigestData, DigestFormatter};
4use crate::core::walker::FileInfo;
5use anyhow::Result;
6
7pub struct XmlFormatter {
9 buffer: String,
10 in_files_section: bool,
11}
12
13impl XmlFormatter {
14 pub fn new() -> Self {
16 Self {
17 buffer: String::from("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<context_creator>\n"),
18 in_files_section: false,
19 }
20 }
21}
22
23impl Default for XmlFormatter {
24 fn default() -> Self {
25 Self::new()
26 }
27}
28
29impl DigestFormatter for XmlFormatter {
30 fn render_header(&mut self, _data: &DigestData) -> Result<()> {
31 Ok(())
33 }
34
35 fn render_statistics(&mut self, data: &DigestData) -> Result<()> {
36 self.buffer.push_str(" <file_summary>\n");
37 self.buffer.push_str(&format!(
38 " <total_files>{}</total_files>\n",
39 data.files.len()
40 ));
41 self.buffer.push_str(" </file_summary>\n");
42 Ok(())
43 }
44
45 fn render_file_tree(&mut self, _data: &DigestData) -> Result<()> {
46 Ok(())
48 }
49
50 fn render_toc(&mut self, _data: &DigestData) -> Result<()> {
51 Ok(())
53 }
54
55 fn render_file_details(&mut self, file: &FileInfo, data: &DigestData) -> Result<()> {
56 if !self.in_files_section {
58 self.buffer.push_str(" <files>\n");
59 self.in_files_section = true;
60 }
61
62 if let Ok(content) = data.cache.get_or_load(&file.path) {
64 self.buffer.push_str(&format!(
65 " <file path=\"{}\">\n",
66 file.relative_path.display()
67 ));
68 self.buffer.push_str(" <![CDATA[");
69 self.buffer.push_str(&content);
70 self.buffer.push_str("]]>\n");
71 self.buffer.push_str(" </file>\n");
72 }
73 Ok(())
74 }
75
76 fn finalize(mut self: Box<Self>) -> String {
77 if self.in_files_section {
79 self.buffer.push_str(" </files>\n");
80 }
81 self.buffer.push_str("</context_creator>\n");
82 self.buffer
83 }
84
85 fn format_name(&self) -> &'static str {
86 "xml"
87 }
88}