use super::bits::push_bits;
use super::mode::EncodeBits;
pub fn bit_length(input: &str) -> usize {
let n = input.chars().count();
let full_triplets = n / 3;
let remainder = n % 3;
let mut bits = 0;
for _ in 0..full_triplets {
bits += 10; }
match remainder {
0 => bits,
1 => bits + 4, 2 => bits + 7, _ => unreachable!(),
}
}
pub fn encode(input: &str, bits: &mut EncodeBits) {
let digits: Vec<u8> = input
.chars()
.map(|c| c.to_digit(10).unwrap() as u8)
.collect();
let n = digits.len();
let full_triplets = n / 3;
let remainder = n % 3;
for i in 0..full_triplets {
let idx = i * 3;
let value = (digits[idx] as u16) * 100 + (digits[idx + 1] as u16) * 10 + (digits[idx + 2] as u16);
push_bits(bits, value as u32, 10);
}
match remainder {
0 => {}
1 => {
push_bits(bits, digits[n - 1] as u32, 4);
}
2 => {
let value = (digits[n - 2] as u16) * 10 + (digits[n - 1] as u16);
push_bits(bits, value as u32, 7);
}
_ => unreachable!(),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_bit_length() {
assert_eq!(bit_length("123"), 10); assert_eq!(bit_length("1234"), 14); assert_eq!(bit_length("12"), 7); assert_eq!(bit_length("1"), 4); assert_eq!(bit_length("12345"), 17); }
#[test]
fn test_encode_triplets() {
let mut bits = EncodeBits::new();
encode("123", &mut bits);
assert_eq!(bits.len(), 10);
}
#[test]
fn test_encode_remainder() {
let mut bits = EncodeBits::new();
encode("12", &mut bits);
assert_eq!(bits.len(), 7);
}
}