#lcov #coverage #gcov


LCOV tracefile parser/merger/filter in pure Rust

10 releases (5 breaking)

0.6.0 Jul 28, 2020
0.5.0 Feb 18, 2019
0.4.2 May 3, 2018
0.4.1 Apr 15, 2018
0.1.2 Feb 10, 2018

#118 in Parser implementations

Download history 3/week @ 2021-02-21 7/week @ 2021-02-28 3/week @ 2021-03-07 2/week @ 2021-03-14 25/week @ 2021-03-21 23/week @ 2021-03-28 22/week @ 2021-04-04 17/week @ 2021-04-11 36/week @ 2021-04-18 5/week @ 2021-04-25 13/week @ 2021-05-02 1/week @ 2021-05-09 11/week @ 2021-05-16 4/week @ 2021-05-23 4/week @ 2021-05-30 13/week @ 2021-06-06

66 downloads per month
Used in lcov-util


1.5K SLoC


Crates.io Docs.rs Travis CI Build Status LICENSE

LCOV tracefile parser/merger/filter in pure Rust.

LCOV is a graphical front-end for coverage testing tool gcov. It collects gcov data for multiple source files and stores them into the file called as "tracefile".

The purpose of this crate is to operate the LCOV tracefile faster than the original LCOV Perl implementation.


Add this to your Cargo.toml:

lcov = "0.6"


See the README of lcov-util.

Data structure

In this crate, the data structure corresponding to each line of the LCOV tracefile is called "LCOV record" and is represented as Record. Each line of the LCOV tracefile is composed of a string representing a kind of the record, a colon, a comma-separated field list:


LCOV record kind is represented as a variant of Record or RecordKind. Each fields of an LCOV record are represented as fields of a struct-like variant of Record.

For details of the LCOV tracefile syntax, see the manpage of geninfo.


Parsing an LCOV tracefile:

use lcov::{Record, RecordKind, Reader};

// `Reader` is an iterator that iterates over `Result<lcov::Record, E>` read from the input buffer.
let mut reader = Reader::open_file("tests/fixtures/report.info")?;

// Collect the read records into a vector.
let records = reader.collect::<Result<Vec<_>, _>>()?;
assert_eq!(records[0], Record::TestName { name: "".into() });
assert_eq!(records[1].kind(), RecordKind::SourceFile);

// Outputs the read records in LCOV tracefile format.
for record in records {
    println!("{}", record);

Createing an LCOV report from String:

use lcov::{Reader, Record};

let input = "\

// `&[u8]` implements `BufRead`, so you can pass it as an argument to `Reader::new`.
let mut reader = Reader::new(input.as_bytes());

let records = reader.collect::<Result<Vec<_>, _>>()?;
assert_eq!(records[0], Record::TestName { name: "test_name".into() });
assert_eq!(records[1], Record::SourceFile { path: "/path/to/source/file.rs".into() });

// Creates an `String` in tracefile format. In this example, it is the same as `input`.
let output = records.into_iter().map(|rec| format!("{}\n", rec)).collect::<String>();
assert_eq!(input, output);

Merging tracefiles:

use lcov::{Record, RecordKind, Report};

// Creates an empty `Report`.
let mut report = Report::new();

// Merges a first file.

// Merges a second file.

// Outputs the merge result in LCOV tracefile format.
for record in report.into_records() {
    println!("{}", record);


This project is licensed under either of

Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)

at your option.


Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in lcov by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.


~20K SLoC