Skip to content

Commit 6ecc4bd

Browse files
feat: Add ability to fetch number of sequences and I-th sequence from FAI index (#377)
* add functions to fetch faidx_nseq and faidx_iseq * rename fetch_n_seqs to n_seqs Co-authored-by: Johannes Köster <[email protected]> * rename fetch_i_seq to seq_name Co-authored-by: Johannes Köster <[email protected]> * add tests for new faidx functions --------- Co-authored-by: Johannes Köster <[email protected]>
1 parent e91b1e2 commit 6ecc4bd

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

src/errors.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ pub enum Error {
3131
// Errors for faidx
3232
#[error("The given position is too large to be converted to i64")]
3333
FaidxPositionTooLarge,
34+
#[error("bad conversion of sequence name")]
35+
FaidxBadSeqName,
3436

3537
// Errors for Tbx
3638
#[error("previous iterator generation failed")]

src/faidx/mod.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,33 @@ impl Reader {
9999
let bytes = self.fetch_seq(name, begin, end)?;
100100
Ok(std::str::from_utf8(bytes).unwrap().to_owned())
101101
}
102+
103+
/// Fetches the number of sequences in the fai index
104+
pub fn n_seqs(&self) -> u64 {
105+
let n = unsafe { htslib::faidx_nseq(self.inner) };
106+
n as u64
107+
}
108+
109+
/// Fetches the i-th sequence name
110+
///
111+
/// # Arguments
112+
///
113+
/// * `i` - index to query
114+
pub fn seq_name(&self, i: i32) -> Result<String> {
115+
let cname = unsafe {
116+
let ptr = htslib::faidx_iseq(self.inner, i);
117+
ffi::CStr::from_ptr(ptr)
118+
};
119+
120+
let out = match cname.to_str() {
121+
Ok(s) => s.to_string(),
122+
Err(_) => {
123+
return Err(Error::FaidxBadSeqName);
124+
}
125+
};
126+
127+
Ok(out)
128+
}
102129
}
103130

104131
#[cfg(test)]
@@ -198,4 +225,17 @@ mod tests {
198225
let res = r.fetch_seq("chr1", position_too_large, position_too_large + 1);
199226
assert_eq!(res, Err(Error::FaidxPositionTooLarge));
200227
}
228+
229+
#[test]
230+
fn faidx_n_seqs() {
231+
let r = open_reader();
232+
assert_eq!(r.n_seqs(), 3);
233+
}
234+
235+
#[test]
236+
fn faidx_seq_name() {
237+
let r = open_reader();
238+
let n = r.seq_name(1).unwrap();
239+
assert_eq!(n, "chr2");
240+
}
201241
}

0 commit comments

Comments
 (0)