use std::{error::Error, io::BufRead};
use noodles::vcf::{header, Header};
pub fn read_header_lenient(mut reader: impl BufRead) -> Result<Header, Box<dyn Error>> {
let mut header = String::new();
let mut buffer = String::new();
while !header.contains("#CHROM\t") {
reader.read_line(&mut buffer)?;
if header_line_needed(&buffer) {
header.push_str(&buffer);
}
buffer.clear();
}
let header = ensure_spec_compliance(&mut header);
let parser = header::Parser::builder().build();
Ok(parser.parse(&header)?)
}
fn header_line_needed(line: &str) -> bool {
line.starts_with("##contig")
|| line.starts_with("##fileformat")
|| line.starts_with("##INFO")
|| line.starts_with("##FILTER")
|| line.starts_with("##FORMAT")
|| line.starts_with("#CHROM\t")
}
fn ensure_spec_compliance(header: &mut str) -> String {
let newheader = header
.replace(
"##FORMAT=<ID=GT,Number=1,Type=Float",
"##FORMAT=<ID=GT,Number=1,Type=String",
)
.replace(
"##INFO=<ID=MQ,Number=1,Type=Integer",
"##INFO=<ID=MQ,Number=1,Type=Float",
);
if header.contains("##fileformat=VCFv4.3") && header.contains("##FORMAT=<ID=AD,Number=1") {
return newheader.replace("##fileformat=VCFv4.3", "##fileformat=VCFv4.2");
}
newheader
}