seqtkrs 0.1.1

A Rust reimplementation of seqtk, a fast and lightweight tool for processing biological sequences in FASTA/FASTQ format
Documentation
//! mergepe命令:合并双端测序的两个FASTQ文件
//!
//! 该命令交替输出两个文件中的序列(read1, read2, read1, read2, ...)

use anyhow::{Context, Result};
use clap::Args;

use crate::core::{SeqReader, SeqRecord, SeqWriter};

#[derive(Args, Debug)]
pub struct MergepeArgs {
    /// 第一个输入文件(R1)
    #[arg(value_name = "in1.fq")]
    pub input1: String,

    /// 第二个输入文件(R2)
    #[arg(value_name = "in2.fq")]
    pub input2: String,
}

pub fn run(args: &MergepeArgs) -> Result<()> {
    // 打开两个输入文件
    let mut reader1 = if args.input1 == "-" {
        SeqReader::from_stdin()
    } else {
        SeqReader::from_path(&args.input1)
            .with_context(|| format!("无法打开输入文件: {}", args.input1))?
    };

    let mut reader2 = if args.input2 == "-" {
        SeqReader::from_stdin()
    } else {
        SeqReader::from_path(&args.input2)
            .with_context(|| format!("无法打开输入文件: {}", args.input2))?
    };

    // 创建输出写入器
    let mut writer = SeqWriter::to_stdout();

    // 用于复用的记录对象
    let mut record1 = SeqRecord::new(Vec::new(), Vec::new());
    let mut record2 = SeqRecord::new(Vec::new(), Vec::new());

    // 交替读取并输出两个文件的序列
    loop {
        let has_r1 = reader1.read_next(&mut record1)?;
        if !has_r1 {
            // 第一个文件已读完
            // 检查第二个文件是否还有剩余记录
            if reader2.read_next(&mut record2)? {
                eprintln!("[W::mergepe] 第1个文件的记录数较少。");
            }
            break;
        }

        let has_r2 = reader2.read_next(&mut record2)?;
        if !has_r2 {
            // 第二个文件已读完,但第一个还有记录
            eprintln!("[W::mergepe] 第2个文件的记录数较少。");
            break;
        }

        // 交替输出
        writer.write_record(&record1)?;
        writer.write_record(&record2)?;
    }

    writer.flush()?;
    Ok(())
}