sigalign_impl/sequence_storage/in_memory/
extensions.rs

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