diff --git a/Cargo.toml b/Cargo.toml index 0026d5d..b920db8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bio-streams" -version = "0.4.0" +version = "0.5.0" edition = "2021" authors = ["jeff-k "] description = "Streaming bioinformatics data types" @@ -13,13 +13,11 @@ readme = "README.md" futures = "0.3" futures-test = "0.3" bio-seq = "0.13" -#bio-seq = { path = "../bio-seq/bio-seq" } [dev-dependencies] flate2 = "1" clap = { version="4", features=["derive"] } bio-seq = "0.13" -#bio-seq = { path = "../bio-seq/bio-seq" } [[example]] name = "fqcheck" diff --git a/src/fasta.rs b/src/fasta.rs index efe0597..eea759d 100644 --- a/src/fasta.rs +++ b/src/fasta.rs @@ -8,15 +8,7 @@ use futures::stream::Stream; use bio_seq::prelude::*; -use crate::Record; - -#[derive(Debug, PartialEq)] -pub enum FastaError { - InvalidId(String), - TruncatedRecord, - InvalidSequence, - FileError, -} +use crate::{FastxError, Reader, Record}; pub struct Fasta> where @@ -50,7 +42,7 @@ impl> + Unpin, T: for<'a> TryFrom<&'a [u8]>> Fasta Option, FastaError>> { + fn parse_record(&mut self) -> Option, FastxError>> { let reader = Pin::get_mut(self.reader.as_mut()); let mut seq_buf: Vec = Vec::new(); @@ -67,13 +59,13 @@ impl> + Unpin, T: for<'a> TryFrom<&'a [u8]>> Fasta> + Unpin, T: for<'a> TryFrom<&'a [u8]>> Fasta s, Err(_) => { - return Some(Err(FastaError::InvalidSequence)); + return Some(Err(FastxError::InvalidSequence("TODO".to_string()))); } }; Some(Ok(Record { @@ -111,8 +103,8 @@ impl> + Unpin, T: for<'a> TryFrom<&'a [u8]>> Fasta Iterator for Fasta> { - type Item = Result>, FastaError>; +impl TryFrom<&'a [u8]>> Iterator for Fasta { + type Item = Result, FastxError>; fn next(&mut self) -> Option { self.parse_record() @@ -120,7 +112,7 @@ impl Iterator for Fasta> { } impl TryFrom<&'a [u8]>> Stream for Fasta { - type Item = Result, FastaError>; + type Item = Result, FastxError>; fn poll_next( self: Pin<&mut Self>, @@ -132,6 +124,8 @@ impl TryFrom<&'a [u8]>> Stream for Fasta< } } +impl TryFrom<&'a [u8]>> Reader for Fasta {} + #[cfg(test)] mod tests { use super::*; diff --git a/src/fastq.rs b/src/fastq.rs index d145f77..6d387bf 100644 --- a/src/fastq.rs +++ b/src/fastq.rs @@ -1,49 +1,15 @@ use core::marker::{PhantomData, Unpin}; -use std::fmt; use std::io::BufRead; use std::pin::Pin; use std::task::{Context, Poll}; -//use std::error; use futures::stream::Stream; use bio_seq::prelude::*; use crate::record::Phred; -use crate::Record; - -#[derive(Debug, PartialEq)] -pub enum FastqError { - InvalidSeparationLine, - InvalidId(String), - TruncatedRecord, - InvalidSequence(String), - InvalidQuality, - FileError, -} - -impl fmt::Display for FastqError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - FastqError::InvalidSeparationLine => write!(f, "Invalid separation character"), - FastqError::InvalidId(id) => write!(f, "Invalid id: {id}"), - FastqError::TruncatedRecord => write!(f, "Truncated record"), - FastqError::InvalidSequence(seq) => write!(f, "Invalid sequence: {seq}"), - FastqError::InvalidQuality => write!(f, "Invalid quailty string"), - FastqError::FileError => write!(f, "File error"), - } - } -} - -/* -impl error::Error for FastqError { - fn source(&self) -> Option<&(dyn error::Error + 'static)> { - match self { - } - } -} - */ +use crate::{FastxError, Reader, Record}; pub struct Fastq> where @@ -71,7 +37,7 @@ impl> + Unpin, T: for<'a> TryFrom<&'a [u8]>> Fastq Option, FastqError>> { + fn parse_record(&mut self) -> Option, FastxError>> { let mut quality = Vec::::new(); let reader = Pin::get_mut(self.reader.as_mut()); @@ -81,7 +47,7 @@ impl> + Unpin, T: for<'a> TryFrom<&'a [u8]>> Fastq> + Unpin, T: for<'a> TryFrom<&'a [u8]>> Fastq parsed_seq, Err(_) => { - return Some(Err(FastqError::InvalidSequence( + return Some(Err(FastxError::InvalidSequence( String::from_utf8_lossy(&self.seq_buf).into_owned(), ))) } @@ -148,8 +114,8 @@ impl> + Unpin, T: for<'a> TryFrom<&'a [u8]>> Fastq Iterator for Fastq> { - type Item = Result>, FastqError>; +impl TryFrom<&'a [u8]>> Iterator for Fastq { + type Item = Result, FastxError>; fn next(&mut self) -> Option { self.parse_record() @@ -157,7 +123,7 @@ impl Iterator for Fastq> { } impl TryFrom<&'a [u8]>> Stream for Fastq { - type Item = Result, FastqError>; + type Item = Result, FastxError>; fn poll_next( self: Pin<&mut Self>, @@ -169,6 +135,8 @@ impl TryFrom<&'a [u8]>> Stream for Fastq< } } +impl TryFrom<&'a [u8]>> Reader for Fastq {} + #[cfg(test)] mod tests { use super::*; diff --git a/src/record.rs b/src/record.rs index dbe069c..7bee696 100644 --- a/src/record.rs +++ b/src/record.rs @@ -1,5 +1,8 @@ use core::fmt; use core::str; +use futures::Stream; + +use crate::FastxError; #[derive(Debug, PartialEq, Copy, Clone)] pub struct Phred(u8); @@ -51,3 +54,8 @@ impl<'a, T: for<'b> TryFrom<&'b [u8]>> Record { unimplemented!() } } + +pub trait Reader TryFrom<&'a [u8]>>: + Iterator, FastxError>> + Stream, FastxError>> +{ +}