in src/cobertura.rs [234:329]
fn get_coverage(
results: &[ResultTuple],
sources: Vec<String>,
demangle: bool,
demangle_options: DemangleOptions,
) -> Coverage {
let packages: Vec<Package> = results
.iter()
.map(|(_, rel_path, result)| {
let all_lines: Vec<u32> = result.lines.keys().cloned().collect();
let end: u32 = result.lines.keys().last().unwrap_or(&0) + 1;
let mut start_indexes: Vec<u32> = Vec::new();
for function in result.functions.values() {
start_indexes.push(function.start);
}
start_indexes.sort_unstable();
let line_from_number = |number| {
let hits = result.lines.get(&number).cloned().unwrap_or_default();
if let Some(branches) = result.branches.get(&number) {
let conditions = branches
.iter()
.enumerate()
.map(|(i, b)| Condition {
cond_type: ConditionType::Jump,
coverage: if *b { 1.0 } else { 0.0 },
number: i,
})
.collect::<Vec<_>>();
Line::Branch {
number,
hits,
conditions,
}
} else {
Line::Plain { number, hits }
}
};
let methods: Vec<Method> = result
.functions
.iter()
.map(|(name, function)| {
let mut func_end = end;
for start in &start_indexes {
if *start > function.start {
func_end = *start;
break;
}
}
let mut lines_in_function: Vec<u32> = Vec::new();
for line in all_lines
.iter()
.filter(|&&x| x >= function.start && x < func_end)
{
lines_in_function.push(*line);
}
let lines: Vec<Line> = lines_in_function
.into_iter()
.map(line_from_number)
.collect();
Method {
name: demangle!(name, demangle, demangle_options),
signature: String::new(),
lines,
}
})
.collect();
let lines: Vec<Line> = all_lines.into_iter().map(line_from_number).collect();
let class = Class {
name: rel_path
.file_stem()
.map(|x| x.to_str().unwrap())
.unwrap_or_default()
.to_string(),
file_name: rel_path.to_str().unwrap_or_default().to_string(),
lines,
methods,
};
Package {
name: rel_path.to_str().unwrap_or_default().to_string(),
classes: vec![class],
}
})
.collect();
Coverage { sources, packages }
}