d4_hts/alignment/
seq_ext.rs

1use 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}