cenc/entities/
alphabet.rs

1#[derive(Clone, PartialEq, Eq, Debug)]
2pub struct Alphabet {
3    pub symbols: Vec<Vec<u8>>,
4    pub symbol_len: usize,
5    pub len: usize,
6}
7
8impl Alphabet {
9    fn empty() -> Self {
10        Self {
11            symbols: vec![],
12            symbol_len: 0,
13            len: 0,
14        }
15    }
16
17    fn new(symbol_len: usize, mut symbols: Vec<Vec<u8>>) -> Self {
18        symbols.sort();
19        let len = symbols.len();
20        Self {
21            symbol_len,
22            symbols,
23            len,
24        }
25    }
26
27    pub fn to_bytes(&self) -> Vec<u8> {
28        let mut result = vec![(self.symbol_len as u8).to_le()];
29        for slice in self.symbols.iter() {
30            result.extend_from_slice(slice);
31        }
32        result
33    }
34
35    pub fn parse_bytes(bytes: &[u8]) -> Option<Self> {
36        if bytes.is_empty() {
37            return None;
38        }
39        let symbol_len = u8::from_le(bytes[0]) as usize;
40        if symbol_len == 0 {
41            return None;
42        }
43        let len = (bytes.len() - 1) / symbol_len;
44        let mut symbols = Vec::with_capacity(len);
45        for i in 0..len {
46            let begin = 1 + (i * symbol_len);
47            if begin + symbol_len > bytes.len() {
48                return None;
49            }
50            symbols.push(bytes[begin..begin + symbol_len].to_vec())
51        }
52        Some(Self {
53            symbol_len,
54            symbols,
55            len,
56        })
57    }
58
59    pub fn get_index(&self, symbol: &[u8]) -> Option<usize> {
60        self.symbols
61            .binary_search_by(|key| {
62                let slice: &[u8] = key;
63                slice.cmp(symbol)
64            })
65            .ok()
66    }
67
68    pub fn get_symbol(&self, index: usize) -> &[u8] {
69        &self.symbols[index]
70    }
71}
72
73impl Into<Alphabet> for &[u8] {
74    fn into(self) -> Alphabet {
75        if self.is_empty() {
76            return Alphabet::empty();
77        }
78        Alphabet::new(1, self.iter().map(|c| vec![*c]).collect())
79    }
80}
81
82impl Into<Alphabet> for Vec<u8> {
83    fn into(self) -> Alphabet {
84        if self.is_empty() {
85            return Alphabet::empty();
86        }
87        let slice: &[u8] = &self;
88        slice.into()
89    }
90}
91
92impl Into<Alphabet> for &[&[u8]] {
93    fn into(self) -> Alphabet {
94        if self.is_empty() {
95            return Alphabet::empty();
96        }
97        let symbol_len = self[0].len();
98        let mut vec = Vec::with_capacity(self.len());
99        for slice in self {
100            assert_eq!(slice.len(), symbol_len);
101            vec.push(slice.to_vec())
102        }
103        Alphabet::new(symbol_len, vec)
104    }
105}
106
107impl Into<Alphabet> for Vec<&[u8]> {
108    fn into(self) -> Alphabet {
109        if self.is_empty() {
110            return Alphabet::empty();
111        }
112        let link: &[&[u8]] = &self;
113        link.into()
114    }
115}
116
117impl Into<Alphabet> for &[Vec<u8>] {
118    fn into(self) -> Alphabet {
119        if self.is_empty() {
120            return Alphabet::empty();
121        }
122        let symbol_len = self[0].len();
123        for slice in self {
124            assert_eq!(slice.len(), symbol_len);
125        }
126        Alphabet::new(symbol_len, self.iter().cloned().collect())
127    }
128}
129
130impl Into<Alphabet> for Vec<Vec<u8>> {
131    fn into(self) -> Alphabet {
132        if self.is_empty() {
133            return Alphabet::empty();
134        }
135        let symbol_len = self[0].len();
136        for slice in &self {
137            assert_eq!(slice.len(), symbol_len);
138        }
139        Alphabet::new(symbol_len, self)
140    }
141}
142
143#[cfg(test)]
144mod tests {
145    use super::*;
146    use rstest::rstest;
147
148    #[test]
149    fn test_ser_de_empty() {
150        let bts = Alphabet::empty().to_bytes();
151        assert_eq!(Alphabet::parse_bytes(&bts), None);
152        assert_eq!(Alphabet::parse_bytes(&[]), None);
153    }
154
155    #[rstest]
156    fn test_ser_de(
157        #[values(1, 2)] sym_len: usize,
158        #[values(2, 4, 5, 7, 8, 10, 16, 20, 25)] sym_count: usize,
159    ) {
160        let src: Vec<Vec<u8>> = (0..sym_count)
161            .map(|i| (0..sym_len).map(|j| (i + j) as u8).collect())
162            .collect();
163        let alphabet: Alphabet = src.clone().into();
164        let bts = alphabet.to_bytes();
165        let restored = Alphabet::parse_bytes(&bts).unwrap();
166        assert_eq!(alphabet, restored);
167    }
168}