1use anyhow::{Context, Result};
2use binseq::BinseqReader;
3use clap::Parser;
4
5pub use anyhow::bail;
6use log::error;
7use paraseq::{fastx, BoxedReader};
8
9#[derive(Parser, Debug)]
10#[clap(next_help_heading = "Paired input options")]
11pub struct MultiPairedInput {
12 #[clap(num_args = 1.., required=true)]
19 pub inputs: Vec<String>,
20}
21impl MultiPairedInput {
22 pub fn is_binseq(&self) -> bool {
23 self.inputs
24 .iter()
25 .all(|path| path.ends_with(".bq") || path.ends_with(".vbq") || path.ends_with("cbq"))
26 }
27
28 pub fn to_binseq_readers(&self) -> Result<Vec<BinseqReader>> {
29 let mut readers = Vec::new();
30 for path in &self.inputs {
31 let reader = BinseqReader::new(path)
32 .context(format!("Failed to open BINSEQ reader for path: {path}"))?;
33 if !reader.is_paired() {
34 error!(
35 "Provided BINSEQ path is not paired. All inputs are expected to be paired: {path}"
36 );
37 bail!("Input file is not paired: {path}");
38 }
39 readers.push(reader);
40 }
41 Ok(readers)
42 }
43
44 pub fn to_paraseq_collection(&self) -> Result<fastx::Collection<BoxedReader>> {
45 if !self.inputs.len().is_multiple_of(2) {
46 error!(
47 "Found {} inputs, expecting an even number of file pairs",
48 self.inputs.len()
49 );
50 bail!("Number of pairs must be even");
51 }
52 let collection =
53 fastx::Collection::from_paths(&self.inputs, fastx::CollectionType::Paired)?;
54 Ok(collection)
55 }
56}