sdb_debugger 0.2.2

Book: Building a Debugger. Rust port of C++ debugger sdb
Documentation
use super::types::Byte64;
use super::types::Byte128;
use bytemuck::NoUninit;
use bytemuck::Pod;
use bytemuck::bytes_of;
use bytemuck::pod_read_unaligned;
use std::ffi::CStr;
use std::ffi::c_char;
use std::mem;

pub fn from_bytes<To: Pod>(bytes: &[u8]) -> To {
    let slice = &bytes[..size_of::<To>()];
    pod_read_unaligned(slice)
}

pub fn to_byte_span<T: Pod>(src: &T) -> &[u8] {
    bytes_of(src)
}

pub fn to_byte_vec<T: Pod>(src: &T) -> Vec<u8> {
    let src_bytes = bytes_of(src);
    src_bytes.to_vec()
}

pub fn to_byte64<T: NoUninit>(src: T) -> Byte64 {
    let mut out: Byte64 = [0; 8];
    let src_bytes = bytes_of(&src);
    out[..src_bytes.len()].copy_from_slice(src_bytes);
    out
}

pub fn to_byte128<T: NoUninit>(src: T) -> Byte128 {
    let mut out: Byte128 = [0; 16];
    let src_bytes = bytes_of(&src);
    out[..src_bytes.len()].copy_from_slice(src_bytes);
    out
}

pub fn from_array_bytes<T: Pod>(data: &[u8]) -> Vec<T> {
    let type_size = mem::size_of::<T>();
    let count = data.len() / type_size;
    assert_eq!(count * type_size, data.len());
    let mut vec = Vec::with_capacity(count);
    for i in 0..count {
        let offset = i * mem::size_of::<T>();
        let obj: T = pod_read_unaligned(&data[offset..offset + mem::size_of::<T>()]);
        vec.push(obj);
    }
    vec
}

pub fn cstr_view(data: &[u8]) -> &str {
    assert!(data.iter().any(|d| { *d == 0 }), "Cannot find c-string");
    let ptr = data.as_ptr() as *const c_char;
    unsafe { CStr::from_ptr(ptr).to_str().unwrap() }
}

pub fn memcpy_bits(
    dest: &mut [u8],
    mut dest_bit: u32,
    src: &[u8],
    mut src_bit: u32,
    mut n_bits: u32,
) {
    while n_bits > 0 {
        let dest_mask = 1u8 << (dest_bit % 8);
        dest[(dest_bit / 8) as usize] &= !dest_mask;

        let src_mask = 1u8 << (src_bit % 8);
        let corresponding_src_bit_set = src[(src_bit / 8) as usize] & src_mask;

        if corresponding_src_bit_set != 0 {
            dest[(dest_bit / 8) as usize] |= dest_mask;
        }

        n_bits -= 1;
        src_bit += 1;
        dest_bit += 1;
    }
}