hyper_byte 0.1.0

An unsafe, near-zero cost (1-2 instructions) byte transmuter to numeric types
Documentation
# Hyper Byte

An unsafe byte slice transmuter for Rust's numeric types, for all three endianness'.<br/>
Additionally included is a simple-to-use byte reader.<br/>
**Supported types:**
* `u8`
* `u16`
* `u32`
* `u64`
* `u128`
* `i8`
* `i16`
* `i32`
* `i64`
* `i128`
* `f16` (If you have the `half` crate)
* `f32`
* `f64`
* `usize`
* `isize`

## Why?

What a great question. There are plenty of ways to do what this crate does, and there are plenty of crates which already do something similar.
### For example

```rust
// Has bound checks for every indexing operation
#[no_mangle]

#[inline(always)]

pub fn read_f64_ne(bytes: &[u8]) -> f64 {
    f64::from_ne_bytes([bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]])
}

// Has more branching and operations involved, and ultimately should be slower
#[no_mangle]

#[inline(always)]

pub fn read_f64_ne(bytes: &[u8]) -> f64 {
    f64::from_ne_bytes(bytes.try_into().expect("Error!"))
}

// My version of this, taking what try_into does and removing the branching,
// thus making it unsafe, but can easily be made safe
#[no_mangle]

#[inline(always)]

pub unsafe fn read_f64_ne(bytes: &[u8]) -> f64 {
    unsafe { f64::from_ne_bytes(*(bytes.as_ptr() as *const [u8; 8])) }
}
```
Benchmarking it is rather difficult since the compiler will do anything to optimize the call out completely (not run the code, I don't mean make it faster).
However, instructions don't lie, and I did manage to create a benchmark, present around line 2256 in [lib.rs](src/lib.rs#L2256-L2284).<br/>
In [Compiler Explorer](https://rust.godbolt.org/z/PfhWzGnnG), you can also see for yourself the instructions for each function.

Running it on my machine, in debug mode, it is around 150% to 200% faster than `try_into`. In release mode, it is closer to only 20% faster.
> [!NOTE]
> While I am very confident that this micro-optimization is faster than the existing solutions, I stand by this only until I'm otherwise corrected.

## Usage

So how do you use this? Either you use the safe, simple reader implemented, or you use the unsafe functions.
### Safe Reader

```rust
use hyper_byte::reader;

#[derive(PartialOrd, PartialEq, Debug)]

struct MyTestStruct {
    unsigned8: u8,
    unsigned16: u16,
    unsigned32: u32,
    unsigned64: u64,
    unsigned128: u128,
    unsigned_size: usize,
    signed8: i8,
    signed16: i16,
    signed32: i32,
    signed64: i64,
    signed128: i128,
    signed_size: isize,
    float16: f16, // if `half` is enabled
    float32: f32,
    float64: f64,
}

fn main() {
    let some_byte_stream : Vec<u8> = Vec::new();
    let mut index = 0;

    let parsed_struct = MyTestStruct {
        unsigned8: reader::read_u8_le(&vector_data, &mut index),
        unsigned16: reader::read_u16_le(&vector_data, &mut index),
        unsigned32: reader::read_u32_le(&vector_data, &mut index),
        unsigned64: reader::read_u64_le(&vector_data, &mut index),
        unsigned128: reader::read_u128_le(&vector_data, &mut index),
        unsigned_size: reader::read_usize_le(&vector_data, &mut index),
        signed8: reader::read_i8_le(&vector_data, &mut index),
        signed16: reader::read_i16_le(&vector_data, &mut index), // if `half` is enabled
        signed32: reader::read_i32_le(&vector_data, &mut index),
        signed64: reader::read_i64_le(&vector_data, &mut index),
        signed128: reader::read_i128_le(&vector_data, &mut index),
        signed_size: reader::read_isize_le(&vector_data, &mut index),
        float16: reader_read_f16_le(&vector_data, &mut index),
        float32: reader::read_f32_le(&vector_data, &mut index),
        float64: reader::read_f64_le(&vector_data, &mut index),
    };
}
```
### Unsafe Functions

```rust
pub fn read_u16_be(array : &[u8], index: &mut usize) -> u16 {
    let current_index = *index;
    let new_index = current_index + size_of::<u16>();
    let ranged_array = &array[current_index..new_index];
    *index = new_index;
    // SAFETY: Ranged array will not allow this function to proceed to unsafe code if there aren't enough bytes to read
    unsafe {
        hyper_byte::read_u16_be(ranged_array)
    }
}
```