qlty_coverage/parser/
clover.rs1use 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}