danlehmann / arbitrary-int

A modern and lightweight implementation of arbitrary integers for Rust
MIT License
32 stars 13 forks source link

Implement from_Xe_bytes, to_Xe_bytes, to_Xe and from_Xe for bitwidths… #17

Closed danlehmann closed 1 year ago

danlehmann commented 1 year ago

… that are a multiple of 8

This needs some macro magic unfortunately as you can't specify const generic bounds like "multiple of 8".

The macros expand to this (for u24):

    pub const fn to_le_bytes(&self) -> [u8; 24 >> 3] {
        let v = self.value();

        [(v >> (0 << 3)) as u8, (v >> (1 << 3)) as u8, (v >> (2 << 3)) as u8, ]
    }

    pub const fn from_le_bytes(from: [u8; 24 >> 3]) -> Self {
        let value = { 0 | (from[0] as u32) << (0 << 3) | (from[1] as u32) << (1 << 3) | (from[2] as u32) << (2 << 3) };
        Self { value }
    }

    pub const fn to_be_bytes(&self) -> [u8; 24 >> 3] {
        let v = self.value();

        [(v >> (24 - 8 - (0 << 3))) as u8, (v >> (24 - 8 - (1 << 3))) as u8, (v >> (24 - 8 - (2 << 3))) as u8, ]
    }

    pub const fn from_be_bytes(from: [u8; 24 >> 3]) -> Self {
        let value = { 0 | (from[0] as u32) << (24 - 8 - (0 << 3)) | (from[1] as u32) << (24 - 8 - (1 << 3)) | (from[2] as u32) << (24 - 8 - (2 << 3)) };
        Self { value }
    }