ntr-io 0.0.1

Idiomatic NT APIs on Rust (I/O)
use ntr_core::raw;

pub type RawHandle = raw::HANDLE;
pub type RawSocket = raw::SOCKET;

pub trait AsRawHandle {
    fn as_raw_handle(&self) -> RawHandle;
}

pub trait FromRawHandle {
    unsafe fn from_raw_handle(handle: RawHandle) -> Self;
}

pub trait IntoRawHandle {
    fn into_raw_handle(self) -> RawHandle;
}

pub trait AsRawSocket {
    fn as_raw_socket(&self) -> RawSocket;
}

pub trait FromRawSocket {
    unsafe fn from_raw_socket(sock: RawSocket) -> Self;
}

pub trait IntoRawSocket {
    fn into_raw_socket(self) -> RawSocket;
}

#[cfg(feature = "net")]
use core::cmp::Ordering;
#[cfg(feature = "net")]
use core::fmt;
#[cfg(feature = "net")]
use core::hash::{Hash, Hasher};

#[cfg(feature = "net")]
#[derive(Clone, Copy)]
#[repr(transparent)]
pub(crate) struct ValidRawSocket(RawSocket);

#[cfg(feature = "net")]
impl ValidRawSocket {
    pub(crate) const fn new(raw: RawSocket) -> Option<Self> {
        #[allow(non_contiguous_range_endpoints)]
        if let 0..RawSocket::MAX = raw {
            Some(unsafe { ValidRawSocket(core::mem::transmute(raw)) })
        } else {
            None
        }
    }

    #[allow(unused)]
    #[inline]
    pub const unsafe fn new_unchecked(raw: RawSocket) -> Self {
        unsafe { core::mem::transmute(raw) }
    }

    #[inline]
    pub const fn as_inner(self) -> RawSocket {
        unsafe { core::mem::transmute(self) }
    }
}

#[cfg(feature = "net")]
impl Eq for ValidRawSocket {}

#[cfg(feature = "net")]
impl PartialEq for ValidRawSocket {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        self.as_inner() == other.as_inner()
    }
}

#[cfg(feature = "net")]
impl Ord for ValidRawSocket {
    #[inline]
    fn cmp(&self, other: &Self) -> Ordering {
        Ord::cmp(&self.as_inner(), &other.as_inner())
    }
}

#[cfg(feature = "net")]
impl PartialOrd for ValidRawSocket {
    #[inline]
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(Ord::cmp(self, other))
    }
}

#[cfg(feature = "net")]
impl Hash for ValidRawSocket {
    fn hash<H: Hasher>(&self, state: &mut H) {
        Hash::hash(&self.as_inner(), state);
    }
}

#[cfg(feature = "net")]
impl fmt::Debug for ValidRawSocket {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        <RawSocket as fmt::Debug>::fmt(&self.as_inner(), f)
    }
}