seqtk-rs 0.1.0

Pure rust version of seqtk
Documentation
use bio::io::{fasta, fastq};
use flate2::read::GzDecoder;
use std::fmt::Display;
use std::fs::File;
use std::io::{self, BufRead, BufReader, BufWriter, Stdout, Write};

pub fn buffer_reader_maybe_gz(path: &str) -> io::Result<Box<dyn BufRead>> {
    let file = File::open(path)?;
    if path.ends_with(".gz") {
        let gz_decoder = GzDecoder::new(file);
        Ok(Box::new(BufReader::new(gz_decoder)))
    } else {
        Ok(Box::new(BufReader::new(file)))
    }
}

pub struct FaReader(fasta::Reader<BufReader<Box<dyn BufRead>>>);
pub struct FqReader(fastq::Reader<BufReader<Box<dyn BufRead>>>);
impl FaReader {
    pub fn new(path: &str) -> io::Result<Self> {
        let reader: Box<dyn BufRead> = buffer_reader_maybe_gz(path)?;
        Ok(Self(fasta::Reader::new(reader)))
    }
    pub fn records(self) -> fasta::Records<BufReader<Box<dyn BufRead + 'static>>> {
        self.0.records()
    }
}
impl FqReader {
    pub fn new(path: &str) -> io::Result<Self> {
        let reader: Box<dyn BufRead> = buffer_reader_maybe_gz(path)?;
        Ok(Self(fastq::Reader::new(reader)))
    }
    pub fn records(self) -> fastq::Records<BufReader<Box<dyn BufRead + 'static>>> {
        self.0.records()
    }
}

pub struct Output {
    writer: BufWriter<std::io::Stdout>,
}
impl Output {
    pub fn new() -> Self {
        let out = std::io::stdout();
        let buffer_out = BufWriter::new(out);
        Output { writer: buffer_out }
    }
    pub fn write<T: Display>(&mut self, result: T) -> io::Result<()> {
        write!(self.writer, "{}", result)
    }
}

pub enum FxWriter {
    Fasta(fasta::Writer<Stdout>),
    Fastq(fastq::Writer<Stdout>),
}
impl FxWriter {
    pub fn new(is_fasta: bool) -> FxWriter {
        let std_out = io::stdout();
        if is_fasta {
            FxWriter::Fasta(fasta::Writer::new(std_out))
        } else {
            FxWriter::Fastq(fastq::Writer::new(std_out))
        }
    }
    pub fn write(
        &mut self,
        id: &str,
        seq: &[u8],
        desc: Option<&str>,
        qual: &[u8],
    ) -> io::Result<()> {
        match self {
            FxWriter::Fasta(ref mut out) => {
                out.write(id, desc, seq)?;
            }
            FxWriter::Fastq(ref mut out) => {
                out.write(id, desc, seq, qual)?;
            }
        }
        Ok(())
    }
}