Skip to content

Commit 3bc5d41

Browse files
committed
tabix: build index
1 parent 2458224 commit 3bc5d41

2 files changed

Lines changed: 57 additions & 0 deletions

File tree

src/errors.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ pub enum Error {
4545
TabixTruncatedRecord,
4646
#[error("invalid tabix index")]
4747
TabixInvalidIndex,
48+
#[error("failed to build tabix index")]
49+
TabixBuildIndex,
50+
#[error("file is not BGZF-compressed")]
51+
TabixNotBgzf,
4852

4953
// Errors for BAM
5054
#[error("error parsing CIGAR string: {msg}")]

src/tbx/mod.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,59 @@ use crate::errors::{Error, Result};
5050
use crate::htslib;
5151
use crate::utils::path_as_bytes;
5252

53+
/// Preset configurations for common file formats.
54+
#[derive(Debug, Clone, Copy)]
55+
pub enum TabixFormat {
56+
Bed,
57+
Gff,
58+
Sam,
59+
Vcf,
60+
}
61+
62+
impl TabixFormat {
63+
fn conf_ptr(self) -> *const htslib::tbx_conf_t {
64+
unsafe {
65+
match self {
66+
TabixFormat::Bed => &htslib::tbx_conf_bed,
67+
TabixFormat::Gff => &htslib::tbx_conf_gff,
68+
TabixFormat::Sam => &htslib::tbx_conf_sam,
69+
TabixFormat::Vcf => &htslib::tbx_conf_vcf,
70+
}
71+
}
72+
}
73+
}
74+
75+
/// Build a tabix index for a BGZF-compressed file.
76+
///
77+
/// This reads the file at `path`, builds a `.tbi` index, and writes it
78+
/// alongside the original file (e.g. `file.bed.gz.tbi`).
79+
///
80+
/// # Arguments
81+
///
82+
/// * `path` - path to the BGZF-compressed file
83+
/// * `format` - the file format preset (determines which columns are chrom/start/end)
84+
/// * `n_threads` - number of threads for decompression (0 for single-threaded)
85+
pub fn build_index<P: AsRef<Path>>(path: P, format: TabixFormat, n_threads: u32) -> Result<()> {
86+
let path_bytes = path_as_bytes(path, true)?;
87+
let c_path = ffi::CString::new(path_bytes).map_err(|_| Error::NonUnicodePath)?;
88+
89+
let ret = unsafe {
90+
htslib::tbx_index_build3(
91+
c_path.as_ptr(),
92+
ptr::null(),
93+
0,
94+
n_threads as i32,
95+
format.conf_ptr(),
96+
)
97+
};
98+
99+
match ret {
100+
0 => Ok(()),
101+
-2 => Err(Error::TabixNotBgzf),
102+
_ => Err(Error::TabixBuildIndex),
103+
}
104+
}
105+
53106
/// A trait for a Tabix reader with a read method.
54107
pub trait Read: Sized {
55108
/// Read next line into the given `Vec<u8>` (i.e., ASCII string).

0 commit comments

Comments
 (0)