cenc/entities/
alphabet.rs1#[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}