compact_genome/implementation/
vec_sequence_store.rs

1//! An ASCII vector based sequence store.
2
3use crate::implementation::vec_sequence::SliceSubGenome;
4use crate::interface::alphabet::{Alphabet, AlphabetCharacter, AlphabetError};
5use crate::interface::sequence::GenomeSequence;
6use crate::interface::sequence_store::{
7    HandleWithLength, HandleWithSubsequence, InverseMappingSequenceStore, SequenceStore,
8};
9use ref_cast::RefCast;
10use std::marker::PhantomData;
11use traitsequence::interface::Sequence;
12
13/// An plain vector based sequence store.
14#[derive(Default, Clone, Eq, PartialEq, Debug)]
15pub struct VectorSequenceStore<AlphabetType: Alphabet> {
16    sequence: Vec<AlphabetType::CharacterType>,
17}
18
19/// A handle of a sequence in an [VectorSequenceStore].
20#[derive(Default, Clone, Copy, Debug, Eq, PartialEq)]
21pub struct VectorSequenceStoreHandle<AlphabetType: Alphabet> {
22    offset: usize,
23    len: usize,
24    phantom_data: PhantomData<AlphabetType>,
25}
26
27impl<AlphabetType: Alphabet> VectorSequenceStore<AlphabetType> {
28    /// Creates a new instance.
29    pub fn new() -> Self {
30        Self {
31            sequence: Vec::new(),
32        }
33    }
34}
35
36impl<AlphabetType: Alphabet + 'static> SequenceStore<AlphabetType>
37    for VectorSequenceStore<AlphabetType>
38{
39    type Handle = VectorSequenceStoreHandle<AlphabetType>;
40    type SequenceRef = SliceSubGenome<AlphabetType>;
41
42    fn add<
43        Sequence: GenomeSequence<AlphabetType, Subsequence> + ?Sized,
44        Subsequence: GenomeSequence<AlphabetType, Subsequence> + ?Sized,
45    >(
46        &mut self,
47        s: &Sequence,
48    ) -> Self::Handle {
49        let offset = self.sequence.len();
50        let len = s.len();
51        self.sequence.extend(s.iter().cloned());
52        Self::Handle {
53            offset,
54            len,
55            phantom_data: Default::default(),
56        }
57    }
58
59    fn add_from_iter(
60        &mut self,
61        iter: impl IntoIterator<Item = <AlphabetType as Alphabet>::CharacterType>,
62    ) -> Self::Handle {
63        let offset = self.sequence.len();
64        let iter = iter.into_iter();
65        let (size, _) = iter.size_hint();
66        self.sequence.reserve(size);
67        for character in iter {
68            self.sequence.push(character)
69        }
70
71        let len = self.sequence.len() - offset;
72        Self::Handle {
73            offset,
74            len,
75            phantom_data: Default::default(),
76        }
77    }
78
79    fn add_from_iter_u8<IteratorType: IntoIterator<Item = u8>>(
80        &mut self,
81        iter: IteratorType,
82    ) -> Result<Self::Handle, AlphabetError> {
83        let offset = self.sequence.len();
84        let iter = iter.into_iter();
85        let (size, _) = iter.size_hint();
86        self.sequence.reserve(size);
87        for item in iter {
88            match AlphabetType::ascii_to_character(item) {
89                Ok(character) => self.sequence.push(character),
90                Err(error) => {
91                    self.sequence
92                        .resize(offset, AlphabetType::CharacterType::from_index(0).unwrap());
93                    return Err(error);
94                }
95            }
96        }
97
98        let len = self.sequence.len() - offset;
99        Ok(Self::Handle {
100            offset,
101            len,
102            phantom_data: Default::default(),
103        })
104    }
105
106    fn get<'this: 'result, 'handle: 'result, 'result>(
107        &'this self,
108        handle: &'handle Self::Handle,
109    ) -> &'result Self::SequenceRef {
110        SliceSubGenome::ref_cast(&self.sequence[handle.offset..handle.offset + handle.len])
111    }
112}
113
114impl<AlphabetType: Alphabet + 'static> InverseMappingSequenceStore<AlphabetType>
115    for VectorSequenceStore<AlphabetType>
116{
117    fn map_sequence_ref_to_handle(&self, sequence_ref: &Self::SequenceRef) -> Self::Handle {
118        Self::Handle {
119            offset: (sequence_ref.slice.as_ptr() as usize) - (self.sequence.as_ptr() as usize),
120            len: sequence_ref.len(),
121            phantom_data: Default::default(),
122        }
123    }
124}
125
126impl<AlphabetType: Alphabet> HandleWithLength for VectorSequenceStoreHandle<AlphabetType> {
127    fn len(&self) -> usize {
128        self.len
129    }
130}
131
132impl<AlphabetType: Alphabet> HandleWithSubsequence<core::ops::Range<usize>>
133    for VectorSequenceStoreHandle<AlphabetType>
134{
135    fn subsequence_handle(&self, range: core::ops::Range<usize>) -> Self {
136        let result = Self {
137            offset: self.offset + range.start,
138            len: range.end - range.start,
139            phantom_data: self.phantom_data,
140        };
141        debug_assert!(self.offset + self.len >= result.offset + result.len);
142        result
143    }
144}