use std::convert::TryFrom;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::Path;
use crate::models::{Transcript, TranscriptRead, Transcripts};
use crate::utils::errors::{ParseRefGeneError, ReadWriteError};
pub struct Reader<R> {
inner: std::io::BufReader<R>,
}
impl Reader<File> {
pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self, ReadWriteError> {
match File::open(path.as_ref()) {
Ok(file) => Ok(Self::new(file)),
Err(err) => Err(ReadWriteError::new(err)),
}
}
}
impl<R: std::io::Read> Reader<R> {
pub fn new(reader: R) -> Self {
Reader {
inner: BufReader::new(reader),
}
}
pub fn with_capacity(capacity: usize, reader: R) -> Self {
Reader {
inner: BufReader::with_capacity(capacity, reader),
}
}
pub fn line(&mut self) -> Option<Result<Transcript, ParseRefGeneError>> {
let mut line = String::new();
match self.inner.read_line(&mut line) {
Ok(_) => {}
Err(x) => {
return Some(Err(ParseRefGeneError {
message: x.to_string(),
}))
}
}
if line.starts_with('#') {
return self.line();
}
if line.is_empty() {
None
} else {
let mut cols: Vec<&str> = line.trim().split('\t').collect();
cols.insert(0, "0");
Some(Transcript::try_from(cols))
}
}
}
impl<R: std::io::Read> TranscriptRead for Reader<R> {
fn transcripts(&mut self) -> Result<Transcripts, ReadWriteError> {
let mut res = Transcripts::new();
while let Some(line) = self.line() {
match line {
Ok(t) => res.push(t),
Err(x) => return Err(ReadWriteError::from(x)),
}
}
Ok(res)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::models::TranscriptRead;
use crate::tests::transcripts;
#[test]
fn test_nm_001365057() {
let transcripts = Reader::from_file("tests/data/NM_001365057.2.genepredext")
.unwrap()
.transcripts()
.unwrap();
assert_eq!(
transcripts.by_name("NM_001365057.2")[0],
&transcripts::nm_001365057()
)
}
#[test]
fn test_nm_001365408() {
let transcripts = Reader::from_file("tests/data/NM_001365408.1.genepredext")
.unwrap()
.transcripts()
.unwrap();
assert_eq!(
transcripts.by_name("NM_001365408.1")[0],
&transcripts::nm_001365408()
)
}
#[test]
fn test_nm_001371720() {
let transcripts = Reader::from_file("tests/data/NM_001371720.1.genepredext")
.unwrap()
.transcripts()
.unwrap();
assert_eq!(
transcripts.by_name("NM_001371720.1")[0],
&transcripts::nm_001371720(false)
)
}
#[test]
fn test_nm_201550() {
let transcripts = Reader::from_file("tests/data/NM_201550.4.genepredext")
.unwrap()
.transcripts()
.unwrap();
assert_eq!(
transcripts.by_name("NM_201550.4")[0],
&transcripts::nm_201550()
)
}
}