oxihuman_export/
html_export.rs1#![allow(dead_code)]
7
8#[allow(dead_code)]
10#[derive(Debug, Clone, Default)]
11pub struct HtmlExport {
12 pub title: String,
13 pub sections: Vec<HtmlSection>,
14}
15
16#[allow(dead_code)]
18#[derive(Debug, Clone)]
19pub struct HtmlSection {
20 pub heading: String,
21 pub rows: Vec<[String; 2]>,
22}
23
24#[allow(dead_code)]
26pub fn new_html_export(title: &str) -> HtmlExport {
27 HtmlExport {
28 title: title.to_string(),
29 sections: Vec::new(),
30 }
31}
32
33#[allow(dead_code)]
35pub fn add_html_section(doc: &mut HtmlExport, heading: &str) {
36 doc.sections.push(HtmlSection {
37 heading: heading.to_string(),
38 rows: Vec::new(),
39 });
40}
41
42#[allow(dead_code)]
44pub fn add_html_row(doc: &mut HtmlExport, key: &str, value: &str) {
45 if let Some(sec) = doc.sections.last_mut() {
46 sec.rows.push([key.to_string(), value.to_string()]);
47 }
48}
49
50#[allow(dead_code)]
52pub fn total_row_count(doc: &HtmlExport) -> usize {
53 doc.sections.iter().map(|s| s.rows.len()).sum()
54}
55
56#[allow(dead_code)]
58pub fn section_count(doc: &HtmlExport) -> usize {
59 doc.sections.len()
60}
61
62#[allow(dead_code)]
64pub fn to_html_string(doc: &HtmlExport) -> String {
65 let mut out = format!(
66 "<!DOCTYPE html>\n<html>\n<head><title>{}</title></head>\n<body>\n<h1>{}</h1>\n",
67 doc.title, doc.title
68 );
69 for sec in &doc.sections {
70 out.push_str(&format!("<h2>{}</h2>\n<table border=\"1\">\n", sec.heading));
71 for row in &sec.rows {
72 out.push_str(&format!(
73 "<tr><td>{}</td><td>{}</td></tr>\n",
74 row[0], row[1]
75 ));
76 }
77 out.push_str("</table>\n");
78 }
79 out.push_str("</body>\n</html>");
80 out
81}
82
83#[allow(dead_code)]
85pub fn export_mesh_stats_html(vertex_count: usize, index_count: usize, name: &str) -> String {
86 let mut doc = new_html_export("Mesh Stats");
87 add_html_section(&mut doc, name);
88 add_html_row(&mut doc, "Vertices", &vertex_count.to_string());
89 add_html_row(&mut doc, "Indices", &index_count.to_string());
90 add_html_row(&mut doc, "Triangles", &(index_count / 3).to_string());
91 to_html_string(&doc)
92}
93
94#[allow(dead_code)]
96pub fn html_escape(s: &str) -> String {
97 s.replace('&', "&")
98 .replace('<', "<")
99 .replace('>', ">")
100 .replace('"', """)
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106
107 #[test]
108 fn test_new_html_export_empty() {
109 let doc = new_html_export("Test");
110 assert_eq!(section_count(&doc), 0);
111 assert_eq!(total_row_count(&doc), 0);
112 }
113
114 #[test]
115 fn test_add_section() {
116 let mut doc = new_html_export("T");
117 add_html_section(&mut doc, "Section 1");
118 assert_eq!(section_count(&doc), 1);
119 }
120
121 #[test]
122 fn test_add_row() {
123 let mut doc = new_html_export("T");
124 add_html_section(&mut doc, "S");
125 add_html_row(&mut doc, "key", "val");
126 assert_eq!(total_row_count(&doc), 1);
127 }
128
129 #[test]
130 fn test_to_html_contains_title() {
131 let doc = new_html_export("My Page");
132 let s = to_html_string(&doc);
133 assert!(s.contains("My Page"));
134 }
135
136 #[test]
137 fn test_to_html_contains_table() {
138 let mut doc = new_html_export("T");
139 add_html_section(&mut doc, "S");
140 add_html_row(&mut doc, "k", "v");
141 let s = to_html_string(&doc);
142 assert!(s.contains("<table"));
143 }
144
145 #[test]
146 fn test_to_html_contains_row_data() {
147 let mut doc = new_html_export("T");
148 add_html_section(&mut doc, "S");
149 add_html_row(&mut doc, "vertices", "512");
150 let s = to_html_string(&doc);
151 assert!(s.contains("512"));
152 }
153
154 #[test]
155 fn test_export_mesh_stats_html() {
156 let s = export_mesh_stats_html(100, 300, "head");
157 assert!(s.contains("Vertices"));
158 assert!(s.contains("head"));
159 }
160
161 #[test]
162 fn test_html_escape_ampersand() {
163 assert_eq!(html_escape("a & b"), "a & b");
164 }
165
166 #[test]
167 fn test_html_escape_angle_brackets() {
168 assert_eq!(html_escape("<tag>"), "<tag>");
169 }
170
171 #[test]
172 fn test_doctype_in_output() {
173 let doc = new_html_export("T");
174 let s = to_html_string(&doc);
175 assert!(s.starts_with("<!DOCTYPE html>"));
176 }
177}