pub const INVALID_BYTE: u8 = u8::MAX;
pub const U8_MASK_BOT_5: u8 = 0b00011111;
pub const U8_MASK_BOT_4: u8 = 0b00001111;
pub const U8_MASK_TOP_4: u8 = 0b11110000;
pub const U8_MASK_TOP_3: u8 = 0b11100000;
pub const U8_MASK_BOT_2: u8 = 0b00000011;
pub const U8_MASK_TOP_1: u8 = 0b10000000;
pub const U8_MASK_BOT_1: u8 = 0b00000001;
pub const U8_MASK_TOP_2: u8 = 0b11000000;
pub const U8_MASK_BOT_3: u8 = 0b00000111;
pub const U8_MASK_TOP_5: u8 = 0b11111000;
pub const U8_MASK_BOT_6: u8 = 0b00111111;
pub const U8_MASK_TOP_6: u8 = 0b11111100;
pub fn bits_or_err_u8(dec: &[u8; 256], a: &[u8], i: usize) -> Result<u8, DecodeError> {
let c = a[i];
let o = dec[c as usize];
if o == INVALID_BYTE {
Err(DecodeError::InvalidChar {
char: c as char,
index: i,
})
} else {
Ok(o)
}
}
pub fn bits_or_err_u64(dec: &[u8; 256], a: &[u8], i: usize) -> Result<u64, DecodeError> {
let c = a[i];
let o = dec[c as usize];
if o == INVALID_BYTE {
Err(DecodeError::InvalidChar {
char: c as char,
index: i,
})
} else {
Ok(o as u64)
}
}
pub fn bits_or_err_u128(dec: &[u8; 256], a: &[u8], i: usize) -> Result<u128, DecodeError> {
let c = a[i];
let o = dec[c as usize];
if o == INVALID_BYTE {
Err(DecodeError::InvalidChar {
char: c as char,
index: i,
})
} else {
Ok(o as u128)
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum DecodeError {
InvalidChar { char: char, index: usize },
InvalidLength { length: usize },
}
impl std::fmt::Display for DecodeError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::InvalidChar { char, index } => {
write!(f, "Invalid char of '{char}' at position {index}")
}
Self::InvalidLength { length } => {
write!(f, "Invalid length of {length}")
} }
}
}
impl std::error::Error for DecodeError {}
pub const fn decoder_map_simple<const B: usize>(enc: &[u8; B]) -> [u8; 256] {
let mut dec = [INVALID_BYTE; 256];
let mut i = 0;
while i < B {
dec[enc[i] as usize] = i as u8;
i += 1;
}
dec
}
const fn enc_index<const B: usize>(enc: &[u8; B], c: u8) -> u8 {
let mut j = 0;
while j < B {
if enc[j] == c {
return j as u8;
}
j += 1;
}
INVALID_BYTE
}
pub const fn decoder_map<const B: usize, const N: usize>(
enc: &[u8; B],
from: &[u8; N],
to: &[u8; N],
) -> [u8; 256] {
let mut dec = decoder_map_simple(enc);
let mut i = 0;
while i < N {
if enc_index(enc, from[i]) != INVALID_BYTE {
panic!("Re-mapping a char from encoder!")
}
let j = enc_index(enc, to[i]);
if j == INVALID_BYTE {
panic!("Missing mapped char in encoder!")
}
dec[from[i] as usize] = j;
i += 1;
}
dec
}