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
use std::io; use std::io::prelude::BufRead; use std::iter::Iterator; use error::*; use types::*; pub struct Reader<R> { reader: io::BufReader<R>, } macro_rules! parse_line { ($reader:ident) => {{ let mut buffer = String::new(); $reader.read_line(&mut buffer)?; buffer }}; ($reader:ident, $t:ty) => {{ let mut buffer = String::new(); $reader.read_line(&mut buffer)?; buffer.trim().parse::<$t>()? }} } impl<R: io::Read> Reader<R> { pub fn new(inner: R) -> Self { Reader { reader: io::BufReader::new(inner) } } pub fn read_snapshot(&mut self) -> Result<Snapshot> { let reader = &mut self.reader; let num_atoms = parse_line!(reader, i32); let comment = parse_line!(reader); let mut atoms: Vec<Atom> = Vec::new(); for _ in 0..num_atoms { atoms.push(parse_line!(reader, Atom)); } Ok(Snapshot { comment: comment, atoms: atoms }) } } impl<R: io::Read> Iterator for Reader<R> { type Item = Snapshot; fn next(&mut self) -> Option<Self::Item> { self.read_snapshot().ok() } } #[cfg(test)] mod tests { use super::*; #[test] fn test_reader() { let data: &[u8] = b"\ 3 comment C 1.0 2.0 3.0 O 4.0 3.0 6.0 H 5.0 1.5 4.0"; let mut reader = Reader::new(data); let success = reader.read_snapshot(); assert!(success.is_ok()); let snapshot = success.unwrap(); assert_eq!(3, snapshot.size()); } #[test] fn test_iterator() { let data: &[u8] = b"\ 3 1st snapshot C 1.0 2.0 3.0 O 4.0 3.0 6.0 H 5.0 1.5 4.0 3 2nd snapshot C 1.1 1.9 2.8 O 4.2 3.0 5.9 H 5.0 1.6 4.0"; let mut reader = Reader::new(data); assert!(reader.next().is_some()); assert!(reader.next().is_some()); assert!(reader.next().is_none()); } }