symcode/acute32/
decoder.rs1use bit_vec::BitVec;
2use crate::interfaces::Decoder;
3use super::{Acute32SymcodeConfig, GlyphLabel};
4
5pub struct Acute32Decoder<'a> {
6 #[allow(dead_code)]
7 config: &'a Acute32SymcodeConfig,
8}
9
10impl<'a> Acute32Decoder<'a> {
11 pub fn new(config: &'a Acute32SymcodeConfig) -> Acute32Decoder<'a> {
12 Self { config }
13 }
14}
15
16impl Decoder for Acute32Decoder<'_> {
18 type Symbol = GlyphLabel;
19
20 type Err = &'static str;
21
22 fn decode(&self, encoded_data: Vec<Self::Symbol>) -> Result<BitVec, Self::Err> {
23 let num_bits_per_symbol = self.num_bits_per_symbol();
24 let mut decoded_data = vec![];
25 for &symbol in encoded_data.iter() {
26 if let Some(bit_vec) = GlyphLabel::self_to_bit_vec(symbol, num_bits_per_symbol) {
27 decoded_data.push(bit_vec);
28 } else {
29 return Err("Decoder error: Some recognized glyph is invalid.");
30 }
31 }
32
33 let mut payload = BitVec::from_elem(20, false);
35 let mut checksum: u8 = 0;
36 for i in 0..25 {
37 let glyph_index = i / num_bits_per_symbol;
38 let within_glyph_offset = i % num_bits_per_symbol;
39 let bit = decoded_data[glyph_index].get(within_glyph_offset).unwrap();
40 if i < 20 {
41 payload.set(i, bit);
42 } else {
43 checksum <<= 1;
44 checksum += if bit {1} else {0};
45 }
46 }
47
48 if crczoo::crc5(&payload.to_bytes()) != checksum {
49 Err("Decoder error: Checksum fail")
50 } else {
51 Ok(payload)
52 }
53 }
54
55 fn num_bits_per_symbol(&self) -> usize {
56 crate::math::num_bits_to_store(GlyphLabel::num_variants())
57 }
58}