qlty_coverage/parser/
clover.rs

1use crate::Parser;
2use anyhow::{Context, Result};
3use qlty_types::tests::v1::FileCoverage;
4use serde::Deserialize;
5
6#[derive(Debug, Deserialize)]
7#[serde(rename = "coverage")]
8struct CloverSource {
9    project: Project,
10}
11
12#[derive(Debug, Deserialize)]
13struct Project {
14    file: Vec<File>,
15}
16
17#[derive(Debug, Deserialize, Clone)]
18struct File {
19    name: String,
20    line: Option<Vec<Line>>,
21    metrics: Metrics,
22}
23
24#[derive(Debug, Deserialize, Clone)]
25struct Metrics {
26    loc: i64,
27}
28
29#[derive(Debug, Deserialize, Clone)]
30struct Line {
31    num: i64,
32    count: i64,
33}
34
35#[derive(Debug, Clone, PartialEq, Eq, Default)]
36pub struct Clover {}
37
38impl Clover {
39    pub fn new() -> Self {
40        Self {}
41    }
42}
43
44impl Parser for Clover {
45    fn parse_text(&self, text: &str) -> Result<Vec<FileCoverage>> {
46        let source: CloverSource =
47            serde_xml_rs::from_str(text).with_context(|| "Failed to parse XML text")?;
48
49        let mut file_coverages = vec![];
50
51        for file in source.project.file.iter() {
52            let mut line_hits = Vec::new();
53
54            if let Some(ref lines) = file.line {
55                for line in lines.iter() {
56                    for _x in (line_hits.len() as i64)..(line.num - 1) {
57                        line_hits.push(-1);
58                    }
59
60                    line_hits.push(line.count);
61                }
62            }
63
64            for _x in (line_hits.len() as i64)..file.metrics.loc {
65                line_hits.push(-1);
66            }
67
68            let file_coverage = FileCoverage {
69                path: file.name.clone(),
70                hits: line_hits,
71                ..Default::default()
72            };
73
74            file_coverages.push(file_coverage);
75        }
76
77        Ok(file_coverages)
78    }
79}