1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
use std::convert::AsRef;
use std::fs::File;
use std::io::{BufRead, BufReader, BufWriter, Cursor, Write};
use std::path::Path;
use util::ResultType;
/// Serialize to and from FASTQ.
///
/// # Serialized Format
///
/// ```text
/// @SRR390728.1 1 length=72
/// CATTCTTCACGTAGTTCTCGAGCCTTGGTTTTCAGCGATGGAGAATGACTTTGACAAGCTGAGAGAAGNTNC
/// +SRR390728.1 1 length=72
/// ;;;;;;;;;;;;;;;;;;;;;;;;;;;9;;665142;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96&&&&(
/// ```
pub trait Fastq: Sized {
/// Estimate the size of the resulting FASTQ output to avoid reallocations.
#[inline(always)]
fn estimate_fastq_size(&self) -> usize {
0
}
/// Export model to FASTQ.
///
/// Note that many small writers are made to the writer, so the writer
/// should be buffered.
fn to_fastq<T: Write>(&self, writer: &mut T) -> ResultType<()>;
/// Export model to FASTQ string.
fn to_fastq_string(&self) -> ResultType<String> {
let capacity = self.estimate_fastq_size();
let mut writer = Cursor::new(Vec::with_capacity(capacity));
self.to_fastq(&mut writer)?;
match String::from_utf8(writer.into_inner()) {
Err(e) => Err(Box::new(e)),
Ok(v) => Ok(v),
}
}
/// Export model to FASTQ output file.
#[inline]
fn to_fastq_file<P: AsRef<Path>>(&self, path: P) -> ResultType<()> {
let file = File::create(path)?;
let mut writer = BufWriter::new(file);
self.to_fastq(&mut writer)
}
/// Import model from FASTQ.
fn from_fastq<T: BufRead>(reader: &mut T) -> ResultType<Self>;
/// Import model from FASTQ string.
#[inline]
fn from_fastq_string(text: &str) -> ResultType<Self> {
// Rust uses the contents of the immutable &str as the buffer
// Cursor is then immutable.
let mut reader = Cursor::new(text);
Self::from_fastq(&mut reader)
}
/// Import model from FASTQ file.
#[inline]
fn from_fastq_file<P: AsRef<Path>>(path: P) -> ResultType<Self> {
let file = File::open(path)?;
let mut reader = BufReader::new(file);
Self::from_fastq(&mut reader)
}
}
/// Specialization of the `Fastq` trait for collections.
pub trait FastqCollection: Fastq {
/// Export collection to FASTQ.
///
/// Returns an error if any of the items within the collection
/// are invalid.
///
/// Note that many small writers are made to the writer, so the writer
/// should be buffered.
fn to_fastq_strict<T: Write>(&self, writer: &mut T) -> ResultType<()>;
/// Export collection to FASTQ.
///
/// Returns only errors due to serialization issues, otherwise,
/// exports as many items as possible.
///
/// Note that many small writers are made to the writer, so the writer
/// should be buffered.
fn to_fastq_lenient<T: Write>(&self, writer: &mut T) -> ResultType<()>;
/// Import collection from FASTQ.
///
/// Returns an error if any of the items within the FASTQ document
/// are invalid.
fn from_fastq_strict<T: BufRead>(reader: &mut T) -> ResultType<Self>;
/// Import collection from FASTQ.
///
/// Returns only errors due to deserialization errors, otherwise,
/// imports as many items as possible.
fn from_fastq_lenient<T: BufRead>(reader: &mut T) -> ResultType<Self>;
}