KokaKiwi / rust-hex

A basic crate to encode values to hexadecimal representation. Originally extracted from rustc-serialize.
https://crates.io/crates/hex
Apache License 2.0
201 stars 55 forks source link

Consider how this project would use const-generics before 1.0 release #61

Open Luro02 opened 3 years ago

Luro02 commented 3 years ago

Once const-generics are further stabilized, one could write an encode/decode function that does not error:

#![feature(const_generics, const_evaluatable_checked)]
use std::array::IntoIter;

const HEX_CHARS_LOWER: &[u8; 16] = b"0123456789abcdef";

fn generate_iter(len: usize) -> impl Iterator<Item = (usize, usize)> {
    (0..len).step_by(2).zip((0..len).skip(1).step_by(2))
}

const fn byte2hex(byte: u8, table: &[u8; 16]) -> (u8, u8) {
    let high = table[((byte & 0xf0) >> 4) as usize];
    let low = table[(byte & 0x0f) as usize];

    (high, low)
}

pub fn encode<const N: usize>(bytes: [u8; N]) -> [u8; N * 2] {
    let mut output = [0; { N * 2 }];

    for (byte, (i, j)) in IntoIter::new(bytes).zip(generate_iter(N * 2)) {
        let (high, low) = byte2hex(byte, HEX_CHARS_LOWER);
        output[i] = high;
        output[j] = low;
    }

    output
}

fn main() {
    assert_eq!(encode(*b"kiwi"), *b"6b697769");
}

playground%0A%7D%0A%0A%23%5Bmust_use%5D%0Aconst%20fn%20byte2hex(byte%3A%20u8%2C%20table%3A%20%26%5Bu8%3B%2016%5D)%20-%3E%20(u8%2C%20u8)%20%7B%0A%20%20%20%20let%20high%20%3D%20table%5B((byte%20%26%200xf0)%20%3E%3E%204)%20as%20usize%5D%3B%0A%20%20%20%20let%20low%20%3D%20table%5B(byte%20%26%200x0f)%20as%20usize%5D%3B%0A%0A%20%20%20%20(high%2C%20low)%0A%7D%0A%0Apub%20fn%20encode%3Cconst%20N%3A%20usize%3E(bytes%3A%20%5Bu8%3B%20N%5D)%20-%3E%20%5Bu8%3B%20N%20%202%5D%20%7B%0A%20%20%20%20let%20mut%20output%20%3D%20%5B0%3B%20%7B%20N%20%202%20%7D%5D%3B%0A%0A%20%20%20%20for%20(byte%2C%20(i%2C%20j))%20in%20IntoIter%3A%3Anew(bytes).zip(generate_iter(N%20%202))%20%7B%0A%20%20%20%20%20%20%20%20let%20(high%2C%20low)%20%3D%20byte2hex(byte%2C%20HEX_CHARS_LOWER)%3B%0A%20%20%20%20%20%20%20%20output%5Bi%5D%20%3D%20high%3B%0A%20%20%20%20%20%20%20%20output%5Bj%5D%20%3D%20low%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20output%0A%7D%0A%0Afn%20main()%20%7B%0A%20%20%20%20assert_eq!(encode(b%22kiwi%22)%2C%20*b%226b697769%22)%3B%0A%7D%0A)

I think this should be considered before the 1.0 release (this could either be a new function or it could replace an existing one?).