noodles_sam/alignment/record/
quality_scores.rs

1use std::io;
2
3/// Alignment record quality scores.
4pub trait QualityScores {
5    /// Returns whether there are any scores.
6    fn is_empty(&self) -> bool;
7
8    /// Returns the number of scores.
9    fn len(&self) -> usize;
10
11    /// Returns an iterator over scores.
12    fn iter(&self) -> Box<dyn Iterator<Item = io::Result<u8>> + '_>;
13}
14
15impl<'a> IntoIterator for &'a dyn QualityScores {
16    type Item = io::Result<u8>;
17    type IntoIter = Box<dyn Iterator<Item = Self::Item> + 'a>;
18
19    fn into_iter(self) -> Self::IntoIter {
20        self.iter()
21    }
22}
23
24impl QualityScores for Box<dyn QualityScores + '_> {
25    fn is_empty(&self) -> bool {
26        (**self).is_empty()
27    }
28
29    fn len(&self) -> usize {
30        (**self).len()
31    }
32
33    fn iter(&self) -> Box<dyn Iterator<Item = io::Result<u8>> + '_> {
34        (**self).iter()
35    }
36}
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41
42    #[test]
43    fn test_into_iter() -> io::Result<()> {
44        struct T(Vec<u8>);
45
46        impl QualityScores for T {
47            fn is_empty(&self) -> bool {
48                self.0.is_empty()
49            }
50
51            fn len(&self) -> usize {
52                self.0.len()
53            }
54
55            fn iter(&self) -> Box<dyn Iterator<Item = io::Result<u8>> + '_> {
56                Box::new(self.0.iter().copied().map(Ok))
57            }
58        }
59
60        let quality_scores: &dyn QualityScores = &T(vec![45, 35, 43, 50]);
61
62        assert_eq!(
63            quality_scores.into_iter().collect::<io::Result<Vec<_>>>()?,
64            [45, 35, 43, 50]
65        );
66
67        Ok(())
68    }
69}