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
use std::fmt;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::marker::PhantomData;
use num::Float;
use crate::error::Error;
use crate::util::get_buf;
use std::str::FromStr;
use analytic::traits::ToIterator;
pub struct BedGraph {
filepath: String,
}
impl BedGraph {
pub fn new(filepath: &str) -> Result<BedGraph, Error> {
Ok(BedGraph {
filepath: filepath.to_string(),
})
}
#[inline]
pub fn get_filepath(&self) -> &str {
&self.filepath
}
}
impl<D, E> ToIterator<'_, BedGraphDataLineIter<D>, <BedGraphDataLineIter<D> as Iterator>::Item> for BedGraph
where D: Float + FromStr<Err=E>, E: fmt::Debug {
fn to_iter(&self) -> BedGraphDataLineIter<D> {
let buf = get_buf(&self.filepath).unwrap();
BedGraphDataLineIter {
buf,
filename: self.filepath.clone(),
phantom: PhantomData,
}
}
}
#[derive(Clone, Debug)]
pub struct BedGraphDataLine<D: Float>(String, usize, usize, D);
pub struct BedGraphDataLineIter<D> {
buf: BufReader<File>,
filename: String,
phantom: PhantomData<D>,
}
impl<D: Float + FromStr<Err=E>, E: fmt::Debug> Iterator for BedGraphDataLineIter<D> {
type Item = BedGraphDataLine<D>;
fn next(&mut self) -> Option<Self::Item> {
let mut line = String::new();
loop {
line.clear();
if self.buf.read_line(&mut line).unwrap() == 0 {
return None;
} else {
let mut toks = line.split_whitespace();
let chrom = {
let chrom = toks.next().unwrap();
if chrom.starts_with("#") || chrom == "track" {
continue;
}
chrom.to_string()
};
let start = toks.next().unwrap().parse::<usize>().unwrap();
let end = toks.next().unwrap().parse::<usize>().unwrap();
let value = toks.next().unwrap().parse::<D>().unwrap();
return Some(BedGraphDataLine(chrom, start, end, value));
}
}
}
}