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}