1use crate::{
2 property::Parsable,
3 record::{Bed3, Bed4, Bed5, Bed6},
4};
5
6use std::{
7 io::{BufRead, BufReader, Read},
8 marker::PhantomData,
9};
10
11pub struct LineRecordStream<R: Read, Rec> {
12 reader: BufReader<R>,
13 buffer: String,
14 _p: PhantomData<Rec>,
15}
16
17pub trait LineRecordStreamExt: Read {
18 fn into_record_iter<Record>(self) -> LineRecordStream<Self, Record>
19 where
20 Self: Sized,
21 {
22 let reader = BufReader::new(self);
23 LineRecordStream {
24 reader,
25 buffer: String::with_capacity(4096),
26 _p: PhantomData,
27 }
28 }
29}
30
31impl<R: Read> LineRecordStreamExt for R {}
32
33impl<R: Read> Iterator for LineRecordStream<R, Bed3> {
34 type Item = Bed3;
35 fn next(&mut self) -> Option<Self::Item> {
36 self.buffer.clear();
37 self.reader.read_line(&mut self.buffer).ok()?;
38 let (parsed, _) = Bed3::parse(self.buffer.trim_end())?;
39 Some(parsed)
40 }
41}
42
43impl<'a, R: Read> Iterator for LineRecordStream<R, Bed4<'a>> {
44 type Item = Bed4<'a>;
45 fn next(&mut self) -> Option<Self::Item> {
46 self.buffer.clear();
47 self.reader.read_line(&mut self.buffer).ok()?;
48 let (parsed, _) = Bed4::parse(unsafe { std::mem::transmute(self.buffer.trim_end()) })?;
49 Some(parsed)
50 }
51}
52
53impl<'a, R: Read> Iterator for LineRecordStream<R, Bed5<'a>> {
54 type Item = Bed5<'a>;
55 fn next(&mut self) -> Option<Self::Item> {
56 self.buffer.clear();
57 self.reader.read_line(&mut self.buffer).ok()?;
58 let (parsed, _) = Bed5::parse(unsafe { std::mem::transmute(self.buffer.trim_end()) })?;
59 Some(parsed)
60 }
61}
62
63impl<'a, R: Read> Iterator for LineRecordStream<R, Bed6<'a>> {
64 type Item = Bed6<'a>;
65 fn next(&mut self) -> Option<Self::Item> {
66 self.buffer.clear();
67 self.reader.read_line(&mut self.buffer).ok()?;
68 let (parsed, _) = Bed6::parse(unsafe { std::mem::transmute(self.buffer.trim_end()) })?;
69 Some(parsed)
70 }
71}