noodles_csi/io/
indexed_reader.rsuse std::io::{self, Read, Seek};
use noodles_bgzf as bgzf;
use noodles_core::Region;
use super::{indexed_records::Record, Query};
use crate::BinningIndex;
pub struct IndexedReader<R, I> {
inner: R,
index: I,
}
impl<R, I> IndexedReader<bgzf::Reader<R>, I>
where
R: Read,
I: BinningIndex,
{
pub fn new(inner: R, index: I) -> Self {
Self {
inner: bgzf::Reader::new(inner),
index,
}
}
pub fn get_ref(&self) -> &bgzf::Reader<R> {
&self.inner
}
pub fn get_mut(&mut self) -> &mut bgzf::Reader<R> {
&mut self.inner
}
pub fn into_inner(self) -> bgzf::Reader<R> {
self.inner
}
pub fn index(&self) -> &I {
&self.index
}
}
impl<R, I> IndexedReader<bgzf::Reader<R>, I>
where
R: Read + Seek,
I: BinningIndex,
{
pub fn query<'r>(
&'r mut self,
region: &'r Region,
) -> io::Result<impl Iterator<Item = io::Result<Record>> + 'r> {
let header = self
.index
.header()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput, "missing index header"))?;
let reference_sequence_id = header
.reference_sequence_names()
.get_index_of(region.name())
.ok_or_else(|| {
io::Error::new(
io::ErrorKind::InvalidInput,
"missing reference sequence name",
)
})?;
let chunks = self.index.query(reference_sequence_id, region.interval())?;
Ok(Query::new(&mut self.inner, chunks)
.indexed_records(header)
.filter_by_region(region))
}
}