use std::fs;
use std::io;
use std::path::PathBuf;
use rayon::iter::{ParallelBridge, ParallelIterator};
use crate::errors;
use crate::io::fasta;
#[derive(Debug, StructOpt)]
#[structopt(verbatim_doc_comment)]
pub struct PeptToLca {
#[structopt(short = "o", long = "one-on-one")]
pub one_on_one: bool,
#[structopt(parse(from_os_str))]
pub fst_file: PathBuf,
#[structopt(short = "m", long = "in-memory")]
pub fst_in_memory: bool,
#[structopt(short = "c", long = "chunksize", default_value = "240")]
pub chunk_size: usize,
}
pub fn pept2lca(args: PeptToLca) -> errors::Result<()> {
let fst = if args.fst_in_memory {
let bytes = fs::read(args.fst_file)?;
fst::Map::from_bytes(bytes)?
} else {
unsafe { fst::Map::from_path(args.fst_file) }?
};
let default = if args.one_on_one { Some(0) } else { None };
fasta::Reader::new(io::stdin(), false)
.records()
.chunked(args.chunk_size)
.par_bridge()
.map(|chunk| {
let chunk = chunk?;
let mut chunk_output = String::new();
for read in chunk {
chunk_output.push_str(&format!(">{}\n", read.header));
for seq in read.sequence {
if let Some(lca) = fst.get(&seq).map(Some).unwrap_or(default) {
chunk_output.push_str(&format!("{}\n", lca));
}
}
}
print!("{}", chunk_output);
Ok(())
})
.collect()
}