socket9 0.1.0-alpha.1

Extended untilities for the networking/unix sockets and raw network sockets
Documentation
use std::{io::{self, ErrorKind}, net::SocketAddr};

#[repr(transparent)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct So9SockDomain(pub libc::c_int);

impl So9SockDomain
{
    /// Not specified 
    pub const UNSPEC: Self = Self(0);
    
    /// [libc::AF_INET] type.
    pub const IPV4: Self = Self(libc::AF_INET);
    
    /// [libc::AF_INET6] type.
    pub const IPV6: Self = Self(libc::AF_INET6);
    
    /// [libc::AF_UNIX] type.
    pub const UNIX: Self = Self(libc::AF_UNIX);

    /// [libc::AF_PACKET] type.
    #[cfg(any(target_os = "android", target_os = "linux"))]
    pub const PACKET: Self = Self(libc::AF_PACKET);

    /// [libc::AF_VSOCK] type.
    #[cfg(any(target_os = "android", target_os = "linux"))]
    pub const VSOCK: Self = Self(libc::AF_VSOCK);
}

impl From<u16> for So9SockDomain
{
    fn from(value: u16) -> Self 
    {
        return Self(value as libc::c_int);
    }
}

impl From<So9DomainRange> for So9SockDomain
{
    fn from(domain: So9DomainRange) -> Self 
    {
        match domain
        {
            So9DomainRange::DoInets => todo!(),
            So9DomainRange::DoUnixs => todo!(),
            So9DomainRange::DoOther(_) => todo!(),
        }
    }
}

impl From<SocketAddr> for So9SockDomain
{
    fn from(sa: SocketAddr) -> Self 
    {
        if sa.is_ipv4() == true
        {
            return Self::IPV4;
        }
        else
        {
            return Self::IPV6;
        }
    }
}


/// Determins the socket's possible range of domains i.e `AF_INET` and `AF_INET6` and
/// `AF_UNIX`.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum So9DomainRange
{
    /// A AF_INET | AF_INET6
    DoInets,

    /// A AF_UNIX only
    DoUnixs,

    /// Other, specific
    DoOther(libc::sa_family_t)
}

impl So9DomainRange
{
    pub(crate) 
    fn check_fam(&self, sock_fam: So9SockDomain) -> io::Result<()>
    {
        match (self, sock_fam.0 as i32)
        {
            (Self::DoInets, libc::AF_INET | libc::AF_INET6) |
            (Self::DoUnixs, libc::AF_UNIX) => 
                return Ok(()), 
            (Self::DoOther(other), sf) if *other as i32 == sf =>
                return Ok(()),
            (Self::DoInets, sf) => 
                return Err(
                    io::Error::new(ErrorKind::InvalidData, 
                        format!("sock_fam {} does not belong to Inets group", sf))
                ),
            (Self::DoUnixs, sf) => 
                return Err(
                    io::Error::new(ErrorKind::InvalidData, 
                        format!("sock_fam {} does not belong to Unixs group", sf))
                ),
            (Self::DoOther(other), sf) =>
                return Err(
                    io::Error::new(ErrorKind::InvalidData, 
                        format!("sock_fam {} does not belong to Other group {}", sf, other))
                ), 
        }
    }
}