use std::{ffi::c_int, io::{self, ErrorKind}, net::SocketAddr};
use windows_sys::Win32::Networking::WinSock::{ADDRESS_FAMILY, AF_INET, AF_INET6, AF_UNIX, WSAPROTOCOL_INFOW};
#[repr(transparent)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct So9SockDomain(pub ADDRESS_FAMILY);
impl So9SockDomain
{
pub const UNSPEC: Self = Self(0);
pub const IPV4: Self = Self(AF_INET);
pub const IPV6: Self = Self(AF_INET6);
pub const UNIX: Self = Self(AF_UNIX);
}
impl From<u16> for So9SockDomain
{
fn from(value: u16) -> Self
{
return Self(value as ADDRESS_FAMILY);
}
}
impl From<WSAPROTOCOL_INFOW> for So9SockDomain
{
fn from(value: WSAPROTOCOL_INFOW) -> Self
{
return Self(value.iAddressFamily as u16);
}
}
impl From<SocketAddr> for So9SockDomain
{
fn from(sa: SocketAddr) -> Self
{
if sa.is_ipv4() == true
{
return Self::IPV4;
}
else
{
return Self::IPV6;
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum So9DomainRange
{
DoInets,
DoUnixs,
DoOther(ADDRESS_FAMILY)
}
impl So9DomainRange
{
pub(crate)
fn check_fam(&self, sock_fam: So9SockDomain) -> io::Result<()>
{
match (self, sock_fam.0)
{
(Self::DoInets, AF_INET | AF_INET6) |
(Self::DoUnixs, AF_UNIX) =>
return Ok(()),
(Self::DoOther(other), sf) if *other == 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))
),
}
}
}