1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
use super::Alignment; use super::Nucleotide; use std::ops::Index; pub struct Sequence<'a> { alignment: &'a Alignment<'a>, } impl<'a> Sequence<'a> { pub fn len(&self) -> usize { self.alignment.seq_len() as usize } fn read_numeric(&self, offset: usize) -> u32 { let hts_obj = self.alignment.hts_obj(); let seq = unsafe { hts_obj.data.offset( hts_obj.core.n_cigar as isize * 4 + (hts_obj.core.l_qname as isize) + offset as isize / 2, ) }; let numeric: u32 = if offset % 2 == 0 { (unsafe { *seq } as u32) >> 4 } else { (unsafe { *seq } as u32) & 0xf }; return numeric; } } impl<'a> Index<usize> for Sequence<'a> { type Output = Nucleotide; fn index(&self, offset: usize) -> &Nucleotide { self.read_numeric(offset).into() } } impl<'a> IntoIterator for Sequence<'a> { type Item = Nucleotide; type IntoIter = SequenceIter<'a>; fn into_iter(self) -> SequenceIter<'a> { SequenceIter { seq: self, ofs: 0 } } } pub struct SequenceIter<'a> { seq: Sequence<'a>, ofs: usize, } impl<'a> Iterator for SequenceIter<'a> { type Item = Nucleotide; fn next(&mut self) -> Option<Nucleotide> { if self.ofs < self.seq.len() { let ret = self.seq.read_numeric(self.ofs).into(); self.ofs += 1; return Some(ret); } None } } impl<'a> Alignment<'a> { pub fn sequence(&self) -> Sequence { Sequence { alignment: self } } }