noodles_sam/alignment/record_buf/
sequence.rs

1use std::ops::{Index, IndexMut};
2
3use noodles_core::position::SequenceIndex;
4
5/// An alignment record sequence buffer.
6#[derive(Clone, Debug, Default, Eq, PartialEq)]
7pub struct Sequence(Vec<u8>);
8
9impl Sequence {
10    /// Returns whether there are any bases.
11    pub fn is_empty(&self) -> bool {
12        self.0.is_empty()
13    }
14
15    /// Returns the number of bases.
16    pub fn len(&self) -> usize {
17        self.0.len()
18    }
19
20    /// Returns the base at the given index.
21    pub fn get(&self, i: usize) -> Option<u8> {
22        self.0.get(i).copied()
23    }
24}
25
26impl AsRef<[u8]> for Sequence {
27    fn as_ref(&self) -> &[u8] {
28        &self.0
29    }
30}
31
32impl AsMut<Vec<u8>> for Sequence {
33    fn as_mut(&mut self) -> &mut Vec<u8> {
34        &mut self.0
35    }
36}
37
38impl From<&[u8]> for Sequence {
39    fn from(buf: &[u8]) -> Self {
40        Self::from(Vec::from(buf))
41    }
42}
43
44impl<const N: usize> From<&[u8; N]> for Sequence {
45    fn from(buf: &[u8; N]) -> Self {
46        Self::from(buf.as_slice())
47    }
48}
49
50impl From<Vec<u8>> for Sequence {
51    fn from(bases: Vec<u8>) -> Self {
52        Self(bases)
53    }
54}
55
56impl<I> Index<I> for Sequence
57where
58    I: SequenceIndex<u8>,
59{
60    type Output = I::Output;
61
62    fn index(&self, index: I) -> &Self::Output {
63        index.index(&self.0)
64    }
65}
66
67impl<I> IndexMut<I> for Sequence
68where
69    I: SequenceIndex<u8>,
70{
71    fn index_mut(&mut self, index: I) -> &mut Self::Output {
72        index.index_mut(&mut self.0)
73    }
74}
75
76impl From<Sequence> for Vec<u8> {
77    fn from(sequence: Sequence) -> Self {
78        sequence.0
79    }
80}
81
82impl crate::alignment::record::Sequence for &Sequence {
83    fn is_empty(&self) -> bool {
84        self.0.is_empty()
85    }
86
87    fn len(&self) -> usize {
88        self.0.len()
89    }
90
91    fn get(&self, i: usize) -> Option<u8> {
92        self.0.get(i).copied()
93    }
94
95    fn split_at_checked(
96        &self,
97        mid: usize,
98    ) -> Option<(
99        Box<dyn crate::alignment::record::Sequence + '_>,
100        Box<dyn crate::alignment::record::Sequence + '_>,
101    )> {
102        if mid > self.len() {
103            let (left, right) = self.0.split_at(mid);
104            Some((
105                Box::new(crate::record::Sequence::new(left)),
106                Box::new(crate::record::Sequence::new(right)),
107            ))
108        } else {
109            None
110        }
111    }
112
113    fn iter(&self) -> Box<dyn Iterator<Item = u8> + '_> {
114        Box::new(self.0.iter().copied())
115    }
116}