Skip to content

Commit

Permalink
feat: Add ability to fetch number of sequences and I-th sequence from…
Browse files Browse the repository at this point in the history
… 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]>
  • Loading branch information
jamorrison and johanneskoester authored Mar 30, 2023
1 parent e91b1e2 commit 6ecc4bd
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ pub enum Error {
// Errors for faidx
#[error("The given position is too large to be converted to i64")]
FaidxPositionTooLarge,
#[error("bad conversion of sequence name")]
FaidxBadSeqName,

// Errors for Tbx
#[error("previous iterator generation failed")]
Expand Down
40 changes: 40 additions & 0 deletions src/faidx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,33 @@ impl Reader {
let bytes = self.fetch_seq(name, begin, end)?;
Ok(std::str::from_utf8(bytes).unwrap().to_owned())
}

/// Fetches the number of sequences in the fai index
pub fn n_seqs(&self) -> u64 {
let n = unsafe { htslib::faidx_nseq(self.inner) };
n as u64
}

/// Fetches the i-th sequence name
///
/// # Arguments
///
/// * `i` - index to query
pub fn seq_name(&self, i: i32) -> Result<String> {
let cname = unsafe {
let ptr = htslib::faidx_iseq(self.inner, i);
ffi::CStr::from_ptr(ptr)
};

let out = match cname.to_str() {
Ok(s) => s.to_string(),
Err(_) => {
return Err(Error::FaidxBadSeqName);
}
};

Ok(out)
}
}

#[cfg(test)]
Expand Down Expand Up @@ -198,4 +225,17 @@ mod tests {
let res = r.fetch_seq("chr1", position_too_large, position_too_large + 1);
assert_eq!(res, Err(Error::FaidxPositionTooLarge));
}

#[test]
fn faidx_n_seqs() {
let r = open_reader();
assert_eq!(r.n_seqs(), 3);
}

#[test]
fn faidx_seq_name() {
let r = open_reader();
let n = r.seq_name(1).unwrap();
assert_eq!(n, "chr2");
}
}

0 comments on commit 6ecc4bd

Please sign in to comment.