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