noodles_vcf/io/
indexed_reader.rs

1//! Indexed VCF reader.
2
3mod builder;
4
5pub use self::builder::Builder;
6
7use std::io::{self, BufRead, Read};
8
9use noodles_bgzf as bgzf;
10use noodles_core::Region;
11use noodles_csi::BinningIndex;
12
13use super::{
14    reader::{Query, RecordBufs},
15    Reader,
16};
17use crate::{variant::RecordBuf, Header, Record};
18
19/// An indexed VCF reader.
20pub struct IndexedReader<R> {
21    inner: Reader<R>,
22    index: Box<dyn BinningIndex>,
23}
24
25impl<R> IndexedReader<R> {
26    /// Returns a reference to the underlying reader.
27    pub fn get_ref(&self) -> &R {
28        self.inner.get_ref()
29    }
30
31    /// Returns a mutable reference to the underlying reader.
32    pub fn get_mut(&mut self) -> &mut R {
33        self.inner.get_mut()
34    }
35
36    /// Returns the underlying reader.
37    pub fn into_inner(self) -> R {
38        self.inner.into_inner()
39    }
40}
41
42impl<R> IndexedReader<R>
43where
44    R: BufRead,
45{
46    /// Reads the VCF header.
47    pub fn read_header(&mut self) -> io::Result<Header> {
48        self.inner.read_header()
49    }
50
51    /// Reads a single raw VCF record.
52    pub fn read_record_buf(
53        &mut self,
54        header: &Header,
55        record: &mut RecordBuf,
56    ) -> io::Result<usize> {
57        self.inner.read_record_buf(header, record)
58    }
59
60    /// Returns an iterator over records starting from the current stream position.
61    pub fn record_bufs<'r, 'h: 'r>(&'r mut self, header: &'h Header) -> RecordBufs<'r, 'h, R> {
62        self.inner.record_bufs(header)
63    }
64
65    /// Reads a single record without eagerly parsing its fields.
66    pub fn read_record(&mut self, record: &mut Record) -> io::Result<usize> {
67        self.inner.read_record(record)
68    }
69
70    /// Returns an iterator over records.
71    pub fn records(&mut self) -> impl Iterator<Item = io::Result<Record>> + '_ {
72        self.inner.records()
73    }
74
75    /// Returns the associated index.
76    pub fn index(&self) -> &dyn BinningIndex {
77        &self.index
78    }
79}
80
81impl<R> IndexedReader<R>
82where
83    R: bgzf::io::BufRead + bgzf::io::Seek,
84{
85    /// Returns an iterator over records that intersects the given region.
86    pub fn query<'r, 'h>(
87        &'r mut self,
88        header: &'h Header,
89        region: &Region,
90    ) -> io::Result<Query<'r, 'h, R>> {
91        self.inner.query(header, &self.index, region)
92    }
93}
94
95impl<R> IndexedReader<bgzf::Reader<R>>
96where
97    R: Read,
98{
99    /// Creates an indexed VCF reader.
100    pub fn new<I>(inner: R, index: I) -> Self
101    where
102        I: BinningIndex + 'static,
103    {
104        Self {
105            inner: Reader::new(bgzf::Reader::new(inner)),
106            index: Box::new(index),
107        }
108    }
109}