qlty_coverage/parser/
jacoco.rs1use crate::Parser;
2use anyhow::{Context, Result};
3use qlty_types::tests::v1::FileCoverage;
4use serde::Deserialize;
5use serde_xml_rs;
6
7#[derive(Debug, Deserialize)]
8#[serde(rename = "report")]
9struct JacocoSource {
10 package: Vec<Package>,
11}
12
13#[derive(Debug, Deserialize)]
14struct Package {
15 name: String,
16 sourcefile: Vec<Sourcefile>,
17}
18
19#[derive(Debug, Deserialize)]
20struct Sourcefile {
21 name: String,
22 line: Vec<Line>,
23}
24
25#[derive(Debug, Deserialize)]
26struct Line {
27 nr: i64,
28 ci: i64,
29}
30
31pub struct Jacoco {}
32
33impl Jacoco {
34 pub fn new() -> Self {
35 Self {}
36 }
37}
38
39impl Parser for Jacoco {
40 fn parse_text(&self, text: &str) -> Result<Vec<FileCoverage>> {
41 let source: JacocoSource =
42 serde_xml_rs::from_str(text).with_context(|| "Failed to parse XML text")?;
43 let mut file_coverages: Vec<FileCoverage> = vec![];
44
45 for package in source.package.iter() {
46 for sourcefile in package.sourcefile.iter() {
47 let mut line_hits = Vec::new();
48 for line in sourcefile.line.iter() {
49 for _x in (line_hits.len() as i64)..(line.nr - 1) {
51 line_hits.push(-1)
52 }
53
54 line_hits.push(line.ci);
55 }
56
57 let path = format!("{}/{}", package.name, sourcefile.name);
58
59 let file_coverage = FileCoverage {
60 path,
61 hits: line_hits,
62 ..Default::default()
63 };
64
65 file_coverages.push(file_coverage);
66 }
67 }
68
69 Ok(file_coverages)
70 }
71}