JenkHash 0.3.0

Bob Jenkins hash functions for Rust with a digest-compatible API.
Documentation
use alloc::vec;
use alloc::vec::Vec;

pub(crate) trait ExtSliceU8 {
    #[inline]
    fn read_u32_le(&self) -> u32;
    #[inline]
    fn read_u32_be(&self) -> u32;
    #[inline]
    fn read_u64_le(&self) -> u64;
    fn represent_as_u64(&self) -> Vec<u64>;
}

impl ExtSliceU8 for [u8] {
    fn read_u32_le(&self) -> u32 {
        let has_enough_bytes = self.len() >= size_of::<u32>();

        if has_enough_bytes {
            let data = &self[..size_of::<u32>()];
            u32::from_le_bytes(data.try_into().unwrap())
        } else {
            let mut buf = [0u8; 4];
            buf[..self.len()].copy_from_slice(self);
            u32::from_le_bytes(buf.try_into().unwrap())
        }
    }
    fn read_u32_be(&self) -> u32 {
        let has_enough_bytes = self.len() >= size_of::<u32>();

        if has_enough_bytes {
            let data = &self[..size_of::<u32>()];
            u32::from_be_bytes(data.try_into().unwrap())
        } else {
            let mut buf = [0u8; 4];
            buf[..self.len()].copy_from_slice(self);
            u32::from_be_bytes(buf.try_into().unwrap())
        }
    }
    fn read_u64_le(&self) -> u64 {
        let has_enough_bytes = self.len() >= size_of::<u64>();

        if has_enough_bytes {
            let data = &self[..size_of::<u64>()];
            u64::from_le_bytes(data.try_into().unwrap())
        } else {
            let mut buf = [0u8; 8];
            buf[..self.len()].copy_from_slice(self);
            u64::from_le_bytes(buf.try_into().unwrap())
        }
    }

    fn represent_as_u64(&self) -> Vec<u64> {
        let mut buf = vec![0; (self.len() + 7) / size_of::<u64>()];

        for chunk in self.chunks_exact(size_of::<u64>()) {
            let byte = chunk.read_u64_le();
            buf.push(byte);
        }
        buf.reverse();
        buf
    }
}