use std::{
fmt::Debug,
hash::Hash,
mem::size_of,
convert::TryInto,
};
pub trait HuffLetter: Clone + Eq + Hash + Debug{}
pub trait HuffLetterAsBytes: HuffLetter{
fn try_from_be_bytes(bytes: &[u8]) -> Result<Self, Box<dyn std::error::Error>>;
fn as_be_bytes(&self) -> Box<[u8]>;
}
macro_rules! primitive_letter_impl{
{$($type:ty),+} => {
$(
impl HuffLetter for $type{}
)+
};
}
primitive_letter_impl!{
char,
&str,
String
}
macro_rules! integer_letter_impl{
{$($type:ty),+} => {
$(
primitive_letter_impl!{$type}
impl HuffLetterAsBytes for $type{
fn try_from_be_bytes(bytes: &[u8]) -> Result<Self, Box<dyn std::error::Error>>{
let bytes: [u8; size_of::<$type>()] = bytes.try_into()?;
Ok(Self::from_be_bytes(bytes))
}
fn as_be_bytes(&self) -> Box<[u8]>{
Box::new(self.to_be_bytes())
}
}
)+
};
}
integer_letter_impl!{
u8, u16, u32, u64, usize, u128,
i8, i16, i32, i64, isize, i128
}