noodles_tabix/io/indexed_reader/
builder.rs

1use std::{
2    ffi::{OsStr, OsString},
3    fs::File,
4    io,
5    path::{Path, PathBuf},
6};
7
8use noodles_bgzf as bgzf;
9use noodles_csi::io::IndexedReader;
10
11use crate::Index;
12
13/// An indexed reader builder.
14#[derive(Default)]
15pub struct Builder {
16    index: Option<Index>,
17}
18
19impl Builder {
20    /// Sets an index.
21    pub fn set_index(mut self, index: Index) -> Self {
22        self.index = Some(index);
23        self
24    }
25
26    /// Builds an indexed reader from a path.
27    pub fn build_from_path<P>(self, src: P) -> io::Result<IndexedReader<bgzf::Reader<File>, Index>>
28    where
29        P: AsRef<Path>,
30    {
31        let src = src.as_ref();
32
33        let index = match self.index {
34            Some(index) => index,
35            None => read_associated_index(src)?,
36        };
37
38        let file = File::open(src)?;
39
40        Ok(IndexedReader::new(file, index))
41    }
42}
43
44fn read_associated_index<P>(src: P) -> io::Result<Index>
45where
46    P: AsRef<Path>,
47{
48    crate::read(build_index_src(src, "tbi"))
49}
50
51fn build_index_src<P, S>(src: P, ext: S) -> PathBuf
52where
53    P: AsRef<Path>,
54    S: AsRef<OsStr>,
55{
56    push_ext(src.as_ref().into(), ext)
57}
58
59fn push_ext<S>(path: PathBuf, ext: S) -> PathBuf
60where
61    S: AsRef<OsStr>,
62{
63    let mut s = OsString::from(path);
64    s.push(".");
65    s.push(ext);
66    PathBuf::from(s)
67}
68
69#[cfg(test)]
70mod tests {
71    use std::path::PathBuf;
72
73    use super::*;
74
75    #[test]
76    fn test_push_ext() {
77        assert_eq!(
78            push_ext(PathBuf::from("annotations.gff.gz"), "tbi"),
79            PathBuf::from("annotations.gff.gz.tbi")
80        );
81    }
82}