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
104
105
use std::io::{BufReader, BufRead};
use std::fs::File;
use pest::Parser;
use crate::gbparser::*;
use crate::gbrecord::GBRecord;
use std::collections::HashSet;
#[derive(Debug)]
pub struct GBReader{
file:BufReader<File>,
buffer:String,
leftovers:String,
options:HashSet<ParseOpts>,
}
#[derive(Debug,Eq,PartialOrd, PartialEq,Hash)]
pub enum ParseOpts{
Full,
HoldBuffer,
Alphabet,
Section,
Size,
Definition,
DBLinks,
Source,
Accession,
Organism,
Date,
Features,
References,
Authors,
Comments,
Sequence,
Taxonomy,
FullHeader,
Keywords,
Version,
Conformation,
}
impl GBReader{
pub fn new(filename:&str, options:HashSet<ParseOpts> )->GBReader{
GBReader{
file: BufReader::new(File::open(filename).expect("Failed to open file")),
buffer: String::new(),
leftovers: String::new(),
options
}
}
fn fetch_next_record(&mut self)->Option<GBRecord>{
let mut read_buf=String::new();
let mut bar_count =0;
let mut end = false;
for chars in self.leftovers.chars(){
self.buffer.push(chars);
}
self.leftovers.clear();
while let Ok(n) = self.file.read_line(&mut read_buf){
if n==0||end{
break;
}
for chars in read_buf.chars(){
match chars{
'/' =>{ bar_count+=1;
}
'\n'=>{
if bar_count==2{
end = true;
}
}
_=>bar_count=0
}
if !end{
self.buffer.push(chars)
}else{
self.leftovers.push(chars)
};
}
read_buf.clear();
}
match GBParser::parse(Rule::record,&self.buffer){
Ok(mut r)=>{
let res = GBRecord::from(r.next().unwrap(), &self.options);
self.buffer.clear();
Some(res)
}
Err(e)=>{
eprintln!("{}",self.buffer);
eprintln!("{}",e);
eprintln!("{:?}",e);
self.buffer.clear();
None
}
}
}
}
impl Iterator for GBReader{
type Item = GBRecord;
fn next(&mut self) -> Option<Self::Item> {
self.fetch_next_record()
}
}