use std::io::Read;
use crate::PseudoAln;
use crate::errors::CorruptedInputErr;
type E = Box<dyn std::error::Error>;
pub fn read_bifrost<R: Read>(
conn: &mut R,
) -> Result<PseudoAln, E> {
let separator: char = '\t';
let mut contents: String = String::new();
conn.read_to_string(&mut contents)?;
let mut records = contents.split(separator);
let read_name_bytes = records.next().ok_or(CorruptedInputErr)?;
if read_name_bytes == "query_name" {
return Err(Box::new(crate::errors::BifrostHeaderNotConsumedError{}))
}
let query_name = read_name_bytes.as_bytes().to_vec();
let mut ones: Vec<u32> = Vec::new();
for (idx, record) in records.enumerate() {
if record.parse::<u32>()? > 0 {
ones.push(idx as u32);
}
};
let res = PseudoAln{ones_names: None, query_id: None, ones: Some(ones), query_name: Some(query_name)};
Ok(res)
}
#[cfg(test)]
mod tests {
#[test]
fn read_bifrost_error_if_header_not_consumed() {
use super::read_bifrost;
use std::io::BufRead;
use std::io::BufReader;
use std::io::Cursor;
let mut data: Vec<u8> = b"query_name\tchr.fasta\tplasmid.fasta\n".to_vec();
data.append(&mut b"ERR4035126.1\t121\t0\n".to_vec());
let cursor = Cursor::new(data);
let mut reader = BufReader::new(cursor);
let mut line = String::new();
reader.read_line(&mut line).unwrap();
let got = read_bifrost(&mut line.as_bytes());
assert!(!got.is_ok());
}
#[test]
fn read_bifrost_multiple() {
use crate::PseudoAln;
use super::read_bifrost;
use std::io::BufRead;
use std::io::BufReader;
use std::io::Cursor;
let mut data: Vec<u8> = b"query_name\tchr.fasta\tplasmid.fasta\n".to_vec();
data.append(&mut b"ERR4035126.1\t121\t0\n".to_vec());
data.append(&mut b"ERR4035126.20\t121\t0\n".to_vec());
data.append(&mut b"ERR4035126.16\t51\t0\n".to_vec());
data.append(&mut b"ERR4035126.1262938\t0\t121\n".to_vec());
data.append(&mut b"ERR4035126.1262940\t121\t0\n".to_vec());
data.append(&mut b"ERR4035126.1262954\t0\t121\n".to_vec());
data.append(&mut b"ERR4035126.1262955\t0\t0\n".to_vec());
data.append(&mut b"ERR4035126.651994\t67\t121\n".to_vec());
data.append(&mut b"ERR4035126.651993\t121\t121\n".to_vec());
data.append(&mut b"ERR4035126.1262970\t0\t0\n".to_vec());
let expected = vec![
PseudoAln{ones_names: None, query_id: None, ones: Some(vec![0,]), query_name: Some("ERR4035126.1".as_bytes().to_vec()) },
PseudoAln{ones_names: None, query_id: None, ones: Some(vec![0]), query_name: Some("ERR4035126.20".as_bytes().to_vec()) },
PseudoAln{ones_names: None, query_id: None, ones: Some(vec![0]), query_name: Some("ERR4035126.16".as_bytes().to_vec()) },
PseudoAln{ones_names: None, query_id: None, ones: Some(vec![1]), query_name: Some("ERR4035126.1262938".as_bytes().to_vec()) },
PseudoAln{ones_names: None, query_id: None, ones: Some(vec![0]), query_name: Some("ERR4035126.1262940".as_bytes().to_vec()) },
PseudoAln{ones_names: None, query_id: None, ones: Some(vec![1]), query_name: Some("ERR4035126.1262954".as_bytes().to_vec()) },
PseudoAln{ones_names: None, query_id: None, ones: Some(vec![]), query_name: Some("ERR4035126.1262955".as_bytes().to_vec()) },
PseudoAln{ones_names: None, query_id: None, ones: Some(vec![0, 1]), query_name: Some("ERR4035126.651994".as_bytes().to_vec()) },
PseudoAln{ones_names: None, query_id: None, ones: Some(vec![0, 1]), query_name: Some("ERR4035126.651993".as_bytes().to_vec()) },
PseudoAln{ones_names: None, query_id: None, ones: Some(vec![]), query_name: Some("ERR4035126.1262970".as_bytes().to_vec()) },
];
let cursor = Cursor::new(data);
let mut reader = BufReader::new(cursor);
reader.read_line(&mut String::new()).unwrap();
let got: Vec<PseudoAln> = reader.lines().map(|line| {
read_bifrost(&mut line.unwrap().as_bytes()).unwrap()
}).collect();
assert_eq!(got, expected);
}
}