use anyhow::{Context, Result};
use clap::Args;
use std::fs::File;
use std::io::BufWriter;
use crate::core::{SeqReader, SeqRecord, SeqWriter};
#[derive(Args, Debug)]
pub struct SplitArgs {
#[arg(value_name = "prefix")]
pub prefix: String,
#[arg(value_name = "in.fa")]
pub input: String,
#[arg(short = 'n', default_value = "10")]
pub num_files: usize,
#[arg(short = 'l', default_value = "0")]
pub line_width: usize,
}
pub fn run(args: &SplitArgs) -> Result<()> {
let mut reader = if args.input == "-" {
SeqReader::from_stdin()
} else {
SeqReader::from_path(&args.input)
.with_context(|| format!("无法打开输入文件: {}", args.input))?
};
let mut writers: Vec<SeqWriter<BufWriter<File>>> = Vec::with_capacity(args.num_files);
for i in 0..args.num_files {
let filename = format!("{}.{:05}.fa", args.prefix, i + 1);
let file =
File::create(&filename).with_context(|| format!("无法创建输出文件: {}", filename))?;
let buf_writer = BufWriter::new(file);
let mut writer = SeqWriter::new(buf_writer);
if args.line_width > 0 {
writer = writer.with_line_width(args.line_width);
}
writers.push(writer);
}
let mut record = SeqRecord::new(Vec::new(), Vec::new());
let mut seq_index = 0;
while reader.read_next(&mut record)? {
let file_index = seq_index % args.num_files;
writers[file_index].write_record(&record)?;
seq_index += 1;
}
for writer in &mut writers {
writer.flush()?;
}
Ok(())
}