noodles_tabix/index/
indexer.rs

1use std::io;
2
3use noodles_core::Position;
4use noodles_csi::{
5    self as csi,
6    binning_index::index::{
7        header::ReferenceSequenceNames,
8        reference_sequence::{bin::Chunk, index::LinearIndex},
9        Header,
10    },
11};
12
13use crate::Index;
14
15/// A tabix indexer.
16#[derive(Debug, Default)]
17pub struct Indexer {
18    header: Header,
19    reference_sequence_names: ReferenceSequenceNames,
20    indexer: csi::binning_index::Indexer<LinearIndex>,
21}
22
23impl Indexer {
24    /// Sets an index header.
25    ///
26    /// # Examples
27    ///
28    /// ```
29    /// use noodles_csi::binning_index::index::Header;
30    /// use noodles_tabix::index::Indexer;
31    /// let builder = Indexer::default().set_header(Header::default());
32    /// ```
33    pub fn set_header(&mut self, header: Header) {
34        self.header = header;
35    }
36
37    /// Adds a record.
38    ///
39    /// # Examples
40    ///
41    /// ```
42    /// use noodles_bgzf as bgzf;
43    /// use noodles_core::Position;
44    /// use noodles_csi::binning_index::index::reference_sequence::bin::Chunk;
45    /// use noodles_tabix::index::Indexer;
46    ///
47    /// let mut indexer = Indexer::default();
48    ///
49    /// let start = Position::try_from(8)?;
50    /// let end = Position::try_from(13)?;
51    ///
52    /// indexer.add_record("sq0", start, end, Chunk::new(
53    ///     bgzf::VirtualPosition::from(144),
54    ///     bgzf::VirtualPosition::from(233),
55    /// ))?;
56    /// # Ok::<_, Box<dyn std::error::Error>>(())
57    /// ```
58    pub fn add_record(
59        &mut self,
60        reference_sequence_name: &str,
61        start: Position,
62        end: Position,
63        chunk: Chunk,
64    ) -> io::Result<()> {
65        let (reference_sequence_id, _) = self
66            .reference_sequence_names
67            .insert_full(reference_sequence_name.into());
68
69        let alignment_context = Some((reference_sequence_id, start, end, true));
70        self.indexer.add_record(alignment_context, chunk)
71    }
72
73    /// Builds a tabix index.
74    ///
75    /// # Examples
76    ///
77    /// ```
78    /// use noodles_tabix as tabix;
79    /// let index = tabix::index::Indexer::default().build();
80    /// ```
81    pub fn build(mut self) -> Index {
82        let reference_sequence_count = self.reference_sequence_names.len();
83
84        *self.header.reference_sequence_names_mut() = self.reference_sequence_names;
85
86        self.indexer
87            .set_header(self.header)
88            .build(reference_sequence_count)
89    }
90}