1use std::collections::HashMap;
20use std::path::PathBuf;
21
22#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)]
23pub struct CoverageData {
24 pub data: Vec<CoverageMapping>,
25 #[serde(rename = "type")]
26 pub kind: String,
27 pub version: String,
28}
29
30#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)]
31pub struct CoverageMapping {
32 pub functions: Vec<CoverageFunction>,
33 pub files: Vec<CoverageFile>,
34 pub totals: BinarySummary,
35}
36
37#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)]
38pub struct CoverageFile {
39 pub filename: PathBuf,
40 pub branches: Vec<CoverageBranch>,
41 pub segments: Vec<CoverageFileSegment>,
42 pub expansions: Vec<Expansion>,
43 pub summary: FileSummary,
44}
45
46#[derive(serde::Deserialize, serde::Serialize, Debug, Clone, Copy)]
47#[serde(transparent)]
48pub struct CoverageBranchSerDe([usize; 9]);
49
50#[derive(serde::Deserialize, serde::Serialize, Debug, Clone, Copy)]
51#[serde(from = "CoverageBranchSerDe", into = "CoverageBranchSerDe")]
52pub struct CoverageBranch {
53 pub l1: usize,
54 pub l2: usize,
55 pub c1: usize,
56 pub c2: usize,
57
58 pub execution_count: usize,
59 pub false_execution_count: usize,
60 pub file_id: usize,
61 pub expanded_file_id: usize,
62 pub region_kind: usize,
63}
64
65impl From<CoverageBranchSerDe> for CoverageBranch {
66 fn from(
67 CoverageBranchSerDe(
68 [l1, l2, c1, c2, execution_count, false_execution_count, file_id, expanded_file_id, region_kind],
69 ): CoverageBranchSerDe,
70 ) -> Self {
71 Self {
72 l1,
73 l2,
74 c1,
75 c2,
76 execution_count,
77 false_execution_count,
78 file_id,
79 expanded_file_id,
80 region_kind,
81 }
82 }
83}
84
85impl From<CoverageBranch> for CoverageBranchSerDe {
86 fn from(
87 CoverageBranch {
88 l1,
89 l2,
90 c1,
91 c2,
92 execution_count,
93 false_execution_count,
94 file_id,
95 expanded_file_id,
96 region_kind,
97 }: CoverageBranch,
98 ) -> Self {
99 Self(
100 [l1, l2, c1, c2, execution_count, false_execution_count, file_id, expanded_file_id, region_kind],
101 )
102 }
103}
104
105#[derive(serde::Deserialize, serde::Serialize, Debug, Clone, Copy)]
106struct CoverageFileSegmentSerDe(usize, usize, usize, bool, bool, bool);
107
108#[derive(serde::Deserialize, serde::Serialize, Debug, Clone, Copy)]
109#[serde(from = "CoverageFileSegmentSerDe", into = "CoverageFileSegmentSerDe")]
110pub struct CoverageFileSegment {
111 pub line: usize,
112 pub col: usize,
113 pub count: usize,
114 pub has_count: bool,
115 pub is_region_entry: bool,
116 pub is_gap_region: bool,
117}
118
119impl From<CoverageFileSegmentSerDe> for CoverageFileSegment {
120 fn from(
121 CoverageFileSegmentSerDe(line, col, count, has_count, is_region_entry, is_gap_region): CoverageFileSegmentSerDe,
122 ) -> Self {
123 Self {
124 line,
125 col,
126 count,
127 has_count,
128 is_region_entry,
129 is_gap_region,
130 }
131 }
132}
133
134impl From<CoverageFileSegment> for CoverageFileSegmentSerDe {
135 fn from(
136 CoverageFileSegment {
137 line,
138 col,
139 count,
140 has_count,
141 is_region_entry,
142 is_gap_region,
143 }: CoverageFileSegment,
144 ) -> Self {
145 Self(line, col, count, has_count, is_region_entry, is_gap_region)
146 }
147}
148
149#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)]
150pub struct Expansion {
151 pub branches: Vec<CoverageBranch>,
152 pub filenames: Vec<PathBuf>,
153 pub source_region: Region,
154 pub target_regions: Vec<Region>,
155}
156
157#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)]
158#[serde(transparent)]
159pub struct TargetRegion {
160 pub region: HashMap<String, serde_json::Value>,
161}
162
163#[derive(serde::Deserialize, serde::Serialize, Debug, Clone, Copy)]
164pub struct FileSummary {
165 pub lines: GenericSummary,
166 pub functions: GenericSummary,
167 pub instantiations: GenericSummary,
168 pub regions: RegionsSummary,
169 pub branches: BranchesSummary,
170}
171
172#[derive(serde::Deserialize, serde::Serialize, Debug, Clone, Copy)]
173pub struct BranchesSummary {
174 #[serde(flatten)]
175 pub generic: GenericSummary,
176 pub notcovered: usize,
177}
178
179#[derive(serde::Deserialize, serde::Serialize, Debug, Clone, Copy)]
180pub struct RegionsSummary {
181 #[serde(flatten)]
182 pub generic: GenericSummary,
183 pub notcovered: usize,
184}
185
186#[derive(serde::Deserialize, serde::Serialize, Debug, Clone, Copy)]
187pub struct GenericSummary {
188 pub count: usize,
189 pub covered: usize,
190 pub percent: f64,
191}
192
193#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)]
194pub struct CoverageFunction {
195 pub branches: Vec<CoverageBranch>,
196 pub filenames: Vec<PathBuf>,
197 #[serde(deserialize_with = "deserialize_function_name")]
198 pub name: String,
199 pub count: usize,
200 pub regions: Vec<Region>,
201}
202
203#[derive(serde::Deserialize, serde::Serialize, Debug, Clone, Copy)]
204#[serde(transparent)]
205struct CoverageFunctionRegionSerDe([usize; 8]);
206
207#[derive(serde::Deserialize, serde::Serialize, Debug, Clone, Copy)]
208#[serde(from = "CoverageFunctionRegionSerDe", into = "CoverageFunctionRegionSerDe")]
209pub struct Region {
210 pub l1: usize,
211 pub c1: usize,
212 pub l2: usize,
213 pub c2: usize,
214
215 pub execution_count: usize,
216 pub file_id: usize,
217 pub expanded_file_id: usize,
218 pub region_kind: usize,
219}
220
221impl From<CoverageFunctionRegionSerDe> for Region {
222 fn from(
223 CoverageFunctionRegionSerDe(
224 [l1, c1, l2, c2, execution_count, file_id, expanded_file_id, region_kind],
225 ): CoverageFunctionRegionSerDe,
226 ) -> Self {
227 Self {
228 l1,
229 c1,
230 l2,
231 c2,
232 execution_count,
233 file_id,
234 expanded_file_id,
235 region_kind,
236 }
237 }
238}
239
240impl From<Region> for CoverageFunctionRegionSerDe {
241 fn from(
242 Region {
243 l1,
244 c1,
245 l2,
246 c2,
247 execution_count,
248 file_id,
249 expanded_file_id,
250 region_kind,
251 }: Region,
252 ) -> Self {
253 Self(
254 [l1, c1, l2, c2, execution_count, file_id, expanded_file_id, region_kind],
255 )
256 }
257}
258
259fn deserialize_function_name<'de, D>(deserializer: D) -> Result<String, D::Error>
260where
261 D: serde::Deserializer<'de>,
262{
263 let s = <String as serde::Deserialize>::deserialize(deserializer)?;
264 Ok(rustc_demangle::demangle(&s).to_string())
265}
266
267#[derive(serde::Deserialize, serde::Serialize, Debug, Clone, Copy)]
268pub struct BinarySummary {
269 pub lines: GenericSummary,
270 pub functions: GenericSummary,
271 pub instantiations: GenericSummary,
272 pub regions: RegionsSummary,
273 pub branches: BranchesSummary,
274}