RosettaCodeData/Task/FASTA-format/Rust/fasta-format.rs

64 lines
1.9 KiB
Rust

use std::env;
use std::io::{BufReader, Lines};
use std::io::prelude::*;
use std::fs::File;
fn main() {
let args: Vec<String> = env::args().collect();
let f = File::open(&args[1]).unwrap();
for line in FastaIter::new(f) {
println!("{}", line);
}
}
struct FastaIter<T> {
buffer_lines: Lines<BufReader<T>>,
current_name: Option<String>,
current_sequence: String
}
impl<T: Read> FastaIter<T> {
fn new(file: T) -> FastaIter<T> {
FastaIter { buffer_lines: BufReader::new(file).lines(),
current_name: None,
current_sequence: String::new() }
}
}
impl<T: Read> Iterator for FastaIter<T> {
type Item = String;
fn next(&mut self) -> Option<String> {
while let Some(l) = self.buffer_lines.next() {
let line = l.unwrap();
if line.starts_with(">") {
if self.current_name.is_some() {
let mut res = String::new();
res.push_str(self.current_name.as_ref().unwrap());
res.push_str(": ");
res.push_str(&self.current_sequence);
self.current_name = Some(String::from(&line[1..]));
self.current_sequence.clear();
return Some(res);
} else {
self.current_name = Some(String::from(&line[1..]));
self.current_sequence.clear();
}
continue;
}
self.current_sequence.push_str(line.trim());
}
if self.current_name.is_some() {
let mut res = String::new();
res.push_str(self.current_name.as_ref().unwrap());
res.push_str(": ");
res.push_str(&self.current_sequence);
self.current_name = None;
self.current_sequence.clear();
self.current_sequence.shrink_to_fit();
return Some(res);
}
None
}
}