Skip to main content

Crate fastx

Crate fastx 

Source
Expand description

Fast, streaming FASTA/FASTQ I/O for bioinformatics pipelines.

fastx covers the everyday sequence work that would otherwise pull in BioPython or BioPerl: reading and writing FASTA/FASTQ (plain or gzipped), reverse complementing, translating, quality trimming, assembly statistics and samtools faidx-style random access — with a streaming parser that keeps memory flat regardless of file size.

§Reading

// Format and gzip are detected from the extension and the magic bytes.
for record in fastx::open("reads.fq.gz")? {
    let record = record?;
    println!("{}\t{}\t{:?}", record.id, record.len(), record.gc_content());
}

In a hot loop, reuse one record so parsing does not allocate at all:

use fastx::{FastxReader, Sequence};

let data = b"@r1\nACGTN\n+\nIIIII\n";
let mut reader = FastxReader::new(&data[..]);
let mut record = Sequence::default();
while reader.read_into(&mut record)? {
    assert_eq!(record.len(), 5);
}

For a pass that never keeps a record, FastxReader::read_ref borrows straight from the read buffer and copies nothing at all:

use fastx::FastxReader;

let data = b"@r1\nACGTN\n+\nIIIII\n";
let mut bases = 0;
FastxReader::new(&data[..]).for_each_ref(|record| {
    bases += record.len();
    Ok(())
})?;
assert_eq!(bases, 5);

§Writing

use fastx::{Alphabet, Sequence, WriterBuilder};

let mut writer = WriterBuilder::new()
    .line_width(80)            // FASTA wrapping; 0 disables it
    .validate(Alphabet::Dna)   // reject anything but ACGTN before writing
    .create("contigs.fa.gz")?; // gzip inferred from the extension

writer.write_record(&Sequence::fasta("contig1", b"ACGTACGT"))?;
writer.finish()?;              // always finish: it surfaces gzip errors

§Converting FASTQ to FASTA

use fastx::{FastxReader, FastxWriter, Format};

let fastq = b"@r1 sample\nACGTACGT\n+\nIIIIIIII\n";
let mut out = Vec::new();
let mut writer = FastxWriter::new(&mut out, Format::Fasta).line_width(4);
for record in FastxReader::new(&fastq[..]) {
    writer.write_record(&record?)?;
}
writer.flush()?;
assert_eq!(out, b">r1 sample\nACGT\nACGT\n");

§Cargo features

featuredefaulteffect
gzipyestransparent gzip/BGZF reading and writing via flate2
parallelnoparallel module: batched and chunk-split multicore processing via rayon
zstdnoZstandard reading and writing; needs a C toolchain and Rust 1.85
libdeflatenoswaps BGZF’s deflate for libdeflate: ~2× faster and slightly smaller. Same C toolchain and Rust 1.85
fullnoeverything above

The crate’s own MSRV is 1.74, but a feature inherits the MSRV of what it pulls in: parallel needs 1.80, and zstd and libdeflate need 1.85.

§Design notes

  • Streaming by default. FastxReader holds one growable buffer and one record; a 300 GB FASTQ uses the same memory as a 300 byte one. Lines longer than the buffer grow it, so single-line chromosomes work too.
  • Multi-line records. Wrapped FASTA is joined transparently, and multi-line FASTQ is handled by matching quality length to sequence length rather than by assuming four lines per record — which also makes @ at the start of a quality line harmless.
  • Errors carry line numbers. Malformed input produces Error::Parse with the offending line, not a silent skip.
  • No silent data invention. Writing FASTQ without quality scores is an error; writing a FASTQ record as FASTA drops quality, which is what fq2fa should do.

Re-exports§

pub use crate::borrowed::SequenceRef;
pub use crate::error::Error;
pub use crate::error::ParseError;
pub use crate::error::Result;
pub use crate::format::Compression;
pub use crate::format::CompressionLevel;
pub use crate::format::Format;
pub use crate::index::FastaIndex;
pub use crate::index::IndexedFasta;
pub use crate::paired::Pair;
pub use crate::paired::PairedReader;
pub use crate::paired::PairedWriter;
pub use crate::qual::QualityEncoding;
pub use crate::reader::from_stdin;
pub use crate::reader::open;
pub use crate::reader::BoxedReader;
pub use crate::reader::FastxReader;
pub use crate::reader::ReaderBuilder;
pub use crate::reader::Records;
pub use crate::record::Sequence;
pub use crate::seq::Alphabet;
pub use crate::seq::BaseCounts;
pub use crate::stats::SeqStats;
pub use crate::writer::create;
pub use crate::writer::BoxedWriter;
pub use crate::writer::FastxWriter;
pub use crate::writer::WriterBuilder;

Modules§

bgzf
BGZF: the block-compressed gzip variant used across the samtools ecosystem.
borrowed
Records borrowed from the reader’s buffer, for passes that never keep them.
error
Error types returned by this crate.
format
Format and compression detection.
index
samtools faidx-compatible FASTA indexing and random access.
paired
Paired-end reads, from two files or one interleaved stream.
parallel
Parallel processing helpers (requires the parallel feature).
prelude
Everything you normally need, in one use.
qual
Phred quality scores: decoding, statistics and trimming.
reader
Streaming FASTA/FASTQ reader.
record
The Sequence record type.
seq
Sequence utilities that operate on raw &[u8] slices.
stats
Summary statistics over a set of records — the seqkit stats equivalent.
writer
FASTA/FASTQ writer with optional gzip compression and validation.

Functions§

read_all
Read every record of a file into memory.
read_all_from
Read every record from any reader into memory.
stats_of
Summary statistics for a file, in one call.
write_all
Write records to a file, inferring format and compression from the path.