noodles_bgzf/
indexed_reader.rs

1//! Indexed BGZF reader.
2
3mod builder;
4
5pub use self::builder::Builder;
6
7use std::io::{self, BufRead, Read, Seek, SeekFrom};
8
9use super::{gzi, Reader, VirtualPosition};
10
11/// An indexed BGZF reader.
12pub struct IndexedReader<R> {
13    inner: Reader<R>,
14    index: gzi::Index,
15}
16
17impl<R> IndexedReader<R> {
18    /// Returns a reference to the underlying reader.
19    ///
20    /// # Examples
21    ///
22    /// ```
23    /// # use std::io;
24    /// use noodles_bgzf::{self as bgzf, gzi};
25    /// let reader = bgzf::IndexedReader::new(io::empty(), gzi::Index::default());
26    /// let inner = reader.get_ref();
27    /// ```
28    pub fn get_ref(&self) -> &R {
29        self.inner.get_ref()
30    }
31
32    /// Returns a mutable reference to the underlying reader.
33    ///
34    /// # Examples
35    ///
36    /// ```
37    /// # use std::io;
38    /// use noodles_bgzf::{self as bgzf, gzi};
39    /// let mut reader = bgzf::IndexedReader::new(io::empty(), gzi::Index::default());
40    /// let inner = reader.get_mut();
41    /// ```
42    pub fn get_mut(&mut self) -> &mut R {
43        self.inner.get_mut()
44    }
45
46    /// Unwraps and returns the underlying writer.
47    ///
48    /// # Examples
49    ///
50    /// ```
51    /// # use std::io;
52    /// use noodles_bgzf::{self as bgzf, gzi};
53    /// let reader = bgzf::IndexedReader::new(io::empty(), gzi::Index::default());
54    /// let inner = reader.into_inner();
55    /// ```
56    pub fn into_inner(self) -> R {
57        self.inner.into_inner()
58    }
59}
60
61impl<R> IndexedReader<R>
62where
63    R: Read,
64{
65    /// Creates an indexed BGZF reader.
66    ///
67    /// # Examples
68    ///
69    /// ```
70    /// # use std::io;
71    /// use noodles_bgzf::{self as bgzf, gzi};
72    /// let reader = bgzf::IndexedReader::new(io::empty(), gzi::Index::default());
73    /// ```
74    pub fn new(inner: R, index: gzi::Index) -> Self {
75        Self {
76            inner: Reader::new(inner),
77            index,
78        }
79    }
80
81    /// Returns the current position of the stream.
82    ///
83    /// # Examples
84    ///
85    /// ```
86    /// # use std::io;
87    /// use noodles_bgzf::{self as bgzf, gzi};
88    /// let reader = bgzf::IndexedReader::new(io::empty(), gzi::Index::default());
89    /// assert_eq!(reader.position(), 0);
90    /// ```
91    pub fn position(&self) -> u64 {
92        self.inner.position()
93    }
94
95    /// Returns the current virtual position of the stream.
96    ///
97    /// # Examples
98    ///
99    /// ```
100    /// # use std::io;
101    /// use noodles_bgzf::{self as bgzf, gzi};
102    /// let reader = bgzf::IndexedReader::new(io::empty(), gzi::Index::default());
103    /// assert_eq!(reader.virtual_position(), bgzf::VirtualPosition::from(0));
104    /// ```
105    pub fn virtual_position(&self) -> VirtualPosition {
106        self.inner.virtual_position()
107    }
108
109    /// Returns the associated index.
110    ///
111    /// # Examples
112    ///
113    /// ```
114    /// # use std::io;
115    /// use noodles_bgzf::{self as bgzf, gzi};
116    /// let index = gzi::Index::default();
117    /// let reader = bgzf::IndexedReader::new(io::empty(), index.clone());
118    /// assert_eq!(reader.index(), &index);
119    /// ```
120    pub fn index(&self) -> &gzi::Index {
121        &self.index
122    }
123}
124
125impl<R> Read for IndexedReader<R>
126where
127    R: Read,
128{
129    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
130        self.inner.read(buf)
131    }
132}
133
134impl<R> BufRead for IndexedReader<R>
135where
136    R: Read,
137{
138    fn fill_buf(&mut self) -> io::Result<&[u8]> {
139        self.inner.fill_buf()
140    }
141
142    fn consume(&mut self, amt: usize) {
143        self.inner.consume(amt);
144    }
145}
146
147impl<R> Seek for IndexedReader<R>
148where
149    R: Read + Seek,
150{
151    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
152        match pos {
153            SeekFrom::Start(pos) => self.inner.seek_by_uncompressed_position(&self.index, pos),
154            _ => unimplemented!(),
155        }
156    }
157}