1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
use crate::config::Config; use crate::errors::*; use crate::report::safe_json; use crate::traces::{Trace, TraceMap}; use serde::Serialize; use std::fs::{read_to_string, File}; use std::io::Write; #[derive(Serialize)] struct SourceFile { pub path: Vec<String>, pub content: String, pub traces: Vec<Trace>, pub covered: usize, pub coverable: usize, } #[derive(Serialize)] struct CoverageReport { pub files: Vec<SourceFile>, } pub fn export(coverage_data: &TraceMap, config: &Config) -> Result<(), RunError> { let mut report = CoverageReport { files: Vec::new() }; for (path, traces) in coverage_data.iter() { let content = match read_to_string(path) { Ok(k) => k, Err(e) => { return Err(RunError::Html(format!( "Unable to read source file to string: {}", e.to_string() ))) } }; report.files.push(SourceFile { path: path .components() .map(|c| c.as_os_str().to_string_lossy().to_string()) .collect(), content, traces: traces.clone(), covered: coverage_data.covered_in_path(path), coverable: coverage_data.coverable_in_path(path), }); } let file_path = config.output_directory.join("tarpaulin-report.html"); let mut file = match File::create(file_path) { Ok(k) => k, Err(e) => { return Err(RunError::Html(format!( "File is not writeable: {}", e.to_string() ))) } }; let report_json = match safe_json::to_string_safe(&report) { Ok(k) => k, Err(e) => { return Err(RunError::Html(format!( "Report isn't serializable: {}", e.to_string() ))) } }; let html_write = match write!( file, r##"<!doctype html> <html> <head> <meta charset="utf-8"> <style>{}</style> </head> <body> <div id="root"></div> <script>var data = {};</script> <script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script> <script>{}</script> </body> </html>"##, include_str!("report_viewer.css"), report_json, include_str!("report_viewer.js") ) { Ok(_) => (), Err(e) => return Err(RunError::Html(e.to_string())), }; Ok(html_write) }