grass_runtime/
file.rs

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}