rusty_enet 0.4.0

ENet for Rust (and wasm!) transpiled from C.
Documentation
use core::{alloc::Layout, ffi::c_void, ptr::copy_nonoverlapping};

use crate::{enet_free, enet_malloc, ENET_PACKET_FLAG_NO_ALLOCATE};

pub(crate) type ENetPacketFreeCallback = unsafe fn(*mut ENetPacket);

#[derive(Copy, Clone)]
#[repr(C)]
pub(crate) struct ENetPacket {
    pub(crate) reference_count: usize,
    pub(crate) flags: u32,
    pub(crate) data: *mut u8,
    pub(crate) data_length: usize,
    pub(crate) free_callback: Option<ENetPacketFreeCallback>,
    pub(crate) user_data: *mut c_void,
}
pub(crate) unsafe fn enet_packet_create(
    data: *const u8,
    data_length: usize,
    flags: u32,
) -> *mut ENetPacket {
    let packet: *mut ENetPacket = enet_malloc(Layout::new::<ENetPacket>()).cast();
    if flags & ENET_PACKET_FLAG_NO_ALLOCATE as i32 as u32 != 0 {
        (*packet).data = data.cast_mut();
    } else if data_length <= 0_i32 as usize {
        (*packet).data = core::ptr::null_mut();
    } else {
        (*packet).data = enet_malloc(Layout::array::<u8>(data_length).unwrap());
        if !data.is_null() {
            copy_nonoverlapping(data, (*packet).data, data_length);
        }
    }
    (*packet).reference_count = 0_i32 as usize;
    (*packet).flags = flags;
    (*packet).data_length = data_length;
    (*packet).free_callback = None;
    (*packet).user_data = core::ptr::null_mut();
    packet
}
pub(crate) unsafe fn enet_packet_destroy(packet: *mut ENetPacket) {
    if packet.is_null() {
        return;
    }
    if let Some(callback) = (*packet).free_callback {
        callback(packet);
    }
    if (*packet).flags & ENET_PACKET_FLAG_NO_ALLOCATE as i32 as u32 == 0
        && !((*packet).data).is_null()
    {
        enet_free(
            (*packet).data,
            Layout::array::<u8>((*packet).data_length).unwrap(),
        );
    }
    enet_free(packet.cast(), Layout::new::<ENetPacket>());
}