fn parse_jacoco_report_sourcefile()

in src/parser.rs [624:680]


fn parse_jacoco_report_sourcefile<T: BufRead>(
    parser: &mut Reader<T>,
    buf: &mut Vec<u8>,
) -> Result<JacocoReport, ParserError> {
    let mut lines: BTreeMap<u32, u64> = BTreeMap::new();
    let mut branches: BTreeMap<u32, Vec<bool>> = BTreeMap::new();

    loop {
        match parser.read_event_into(buf) {
            Ok(Event::Start(ref e)) if e.local_name().into_inner() == b"line" => {
                let (mut ci, mut cb, mut mb, mut nr) = (None, None, None, None);
                for a in e.attributes() {
                    let a = a?;
                    match a.key.into_inner() {
                        b"ci" => ci = Some(Decoder {}.decode(&a.value)?.parse::<u64>()?),
                        b"cb" => cb = Some(Decoder {}.decode(&a.value)?.parse::<u64>()?),
                        b"mb" => mb = Some(Decoder {}.decode(&a.value)?.parse::<u64>()?),
                        b"nr" => nr = Some(Decoder {}.decode(&a.value)?.parse::<u32>()?),
                        _ => (),
                    }
                }

                fn try_att<T>(opt: Option<T>, name: &str) -> Result<T, ParserError> {
                    opt.ok_or_else(|| {
                        ParserError::InvalidRecord(format!("Attribute {} not found", name))
                    })
                }

                let ci = try_att(ci, "ci")?;
                let cb = try_att(cb, "cb")?;
                let mb = try_att(mb, "mb")?;
                let nr = try_att(nr, "nr")?;

                if mb > 0 || cb > 0 {
                    // This line is a branch.
                    let mut v = vec![true; cb as usize];
                    v.extend(vec![false; mb as usize]);
                    branches.insert(nr, v);
                } else {
                    // This line is a statement.
                    // JaCoCo does not feature execution counts, so we set the
                    // count to 0 or 1.
                    let hit = u64::from(ci > 0);
                    lines.insert(nr, hit);
                }
            }
            Ok(Event::End(ref e)) if e.local_name().into_inner() == b"sourcefile" => {
                break;
            }
            Err(e) => return Err(ParserError::Parse(e.to_string())),
            _ => {}
        }
        buf.clear();
    }

    Ok(JacocoReport { lines, branches })
}