noodles_sam/alignment/record/
sequence.rs

1/// An alignment record sequence.
2pub trait Sequence {
3    /// Returns whether there are any bases.
4    fn is_empty(&self) -> bool;
5
6    /// Returns the number of bases.
7    fn len(&self) -> usize;
8
9    /// Returns the base at the given index.
10    fn get(&self, i: usize) -> Option<u8>;
11
12    /// Splits the subsequence into two subsequences at the given index.
13    fn split_at_checked(
14        &self,
15        mid: usize,
16    ) -> Option<(Box<dyn Sequence + '_>, Box<dyn Sequence + '_>)>;
17
18    /// Returns an iterator over bases.
19    fn iter(&self) -> Box<dyn Iterator<Item = u8> + '_>;
20}
21
22impl<'a> IntoIterator for &'a dyn Sequence {
23    type Item = u8;
24    type IntoIter = Box<dyn Iterator<Item = Self::Item> + 'a>;
25
26    fn into_iter(self) -> Self::IntoIter {
27        self.iter()
28    }
29}
30
31impl Sequence for Box<dyn Sequence + '_> {
32    fn is_empty(&self) -> bool {
33        (**self).is_empty()
34    }
35
36    fn len(&self) -> usize {
37        (**self).len()
38    }
39
40    fn get(&self, i: usize) -> Option<u8> {
41        (**self).get(i)
42    }
43
44    fn split_at_checked(
45        &self,
46        mid: usize,
47    ) -> Option<(Box<dyn Sequence + '_>, Box<dyn Sequence + '_>)> {
48        (**self).split_at_checked(mid)
49    }
50
51    fn iter(&self) -> Box<dyn Iterator<Item = u8> + '_> {
52        (**self).iter()
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59
60    #[test]
61    fn test_into_iter() {
62        struct T(Vec<u8>);
63
64        impl Sequence for T {
65            fn is_empty(&self) -> bool {
66                self.0.is_empty()
67            }
68
69            fn len(&self) -> usize {
70                self.0.len()
71            }
72
73            fn get(&self, i: usize) -> Option<u8> {
74                self.0.get(i).copied()
75            }
76
77            fn split_at_checked(
78                &self,
79                mid: usize,
80            ) -> Option<(Box<dyn Sequence + '_>, Box<dyn Sequence + '_>)> {
81                let (left, right) = self.0.split_at(mid);
82                Some((Box::new(T(left.to_vec())), Box::new(T(right.to_vec()))))
83            }
84
85            fn iter(&self) -> Box<dyn Iterator<Item = u8> + '_> {
86                Box::new(self.0.iter().copied())
87            }
88        }
89
90        let sequence: &dyn Sequence = &T(vec![b'N', b'D', b'L', b'S']);
91
92        assert_eq!(
93            sequence.into_iter().collect::<Vec<_>>(),
94            [b'N', b'D', b'L', b'S']
95        );
96    }
97}