sigalign_impl/sequence_storage/in_memory/
extensions.rs1use std::io::{Read, Write, Error, ErrorKind};
2
3use capwriter::{Save, Load};
4
5use sigalign_core::reference::extensions::{
6 Serialize,
7 EstimateSize,
8 LabelStorage,
9};
10use crate::core::{EndianType, ReadBytesExt, WriteBytesExt};
11use super::InMemoryStorage;
12
13impl Serialize for InMemoryStorage {
15 fn save_to<W>(&self, mut writer: W) -> Result<(), Error> where
16 W: Write
17 {
18 writer.write_u64::<EndianType>(self.target_count as u64)?;
19 self.concatenated_sequence.save_to(&mut writer)?;
20 self.sequence_index.save_to(&mut writer)?;
21 self.concatenated_label.as_bytes().save_to(&mut writer)?;
22 self.label_index.save_to(&mut writer)?;
23 Ok(())
24 }
25 fn load_from<R>(mut reader: R) -> Result<Self, Error> where
26 R: Read,
27 Self: Sized,
28 {
29 let target_count = reader.read_u64::<EndianType>()? as usize;
30 let concatenated_sequence = Vec::load_from(&mut reader)?;
31 let sequence_index = Vec::load_from(&mut reader)?;
32 let concatenated_label = match String::from_utf8(Vec::<u8>::load_from(&mut reader)?) {
33 Ok(v) => v,
34 Err(_) => return Err(ErrorKind::InvalidData.into()),
35 };
36 let label_index = Vec::load_from(&mut reader)?;
37 Ok(Self {
38 target_count,
39 concatenated_sequence,
40 sequence_index,
41 concatenated_label,
42 label_index,
43 })
44 }
45}
46
47impl EstimateSize for InMemoryStorage {
49 fn serialized_size(&self) -> usize {
50 std::mem::size_of::<u64>()
52 + self.concatenated_sequence.to_be_saved_size()
54 + self.sequence_index.to_be_saved_size()
56 + self.concatenated_label.as_bytes().to_be_saved_size()
58 + self.label_index.to_be_saved_size()
60 }
61}
62impl LabelStorage for InMemoryStorage {
64 fn label_of_target_unchecked(&self, target_index: u32) -> String {
65 unsafe {
66 String::from_utf8_unchecked(
67 self.concatenated_label.as_bytes()[
68 self.label_index[target_index as usize]
69 ..self.label_index[target_index as usize +1]
70 ].to_vec()
71 )
72 }
73 }
74}
75impl InMemoryStorage {
76 pub fn get_label_safely(&self, target_index: u32) -> Option<String> {
77 if target_index as usize >= self.target_count {
78 return None
79 }
80 Some(self.label_of_target_unchecked(target_index))
81 }
82}