use anyhow::{Context, Result};
use clap::Args;
use crate::core::{SeqReader, SeqRecord, SeqWriter};
#[derive(Args, Debug)]
pub struct DropseArgs {
#[arg(value_name = "in.fq", default_value = "-")]
pub input: String,
}
fn names_equal(name1: &[u8], name2: &[u8]) -> bool {
if name1.len() != name2.len() {
return false;
}
let compare_len = if name1.len() > 2
&& name1[name1.len() - 2] == b'/'
&& name2[name2.len() - 2] == b'/'
&& name1[name1.len() - 1].is_ascii_digit()
&& name2[name2.len() - 1].is_ascii_digit()
{
name1.len() - 2
} else {
name1.len()
};
name1[..compare_len] == name2[..compare_len]
}
pub fn run(args: &DropseArgs) -> Result<()> {
let mut reader = if args.input == "-" {
SeqReader::from_stdin()
} else {
SeqReader::from_path(&args.input)
.with_context(|| format!("无法打开输入文件: {}", args.input))?
};
let mut writer = SeqWriter::to_stdout();
let mut last_record: Option<SeqRecord> = None;
let mut current_record = SeqRecord::new(Vec::new(), Vec::new());
while reader.read_next(&mut current_record)? {
if let Some(last) = last_record.take() {
if names_equal(&last.name, ¤t_record.name) {
writer.write_record(&last)?;
writer.write_record(¤t_record)?;
} else {
last_record = Some(current_record.clone());
}
} else {
last_record = Some(current_record.clone());
}
}
writer.flush()?;
Ok(())
}