use std::{io::{self, ErrorKind}, net::SocketAddr};
#[repr(transparent)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct So9SockDomain(pub libc::c_int);
impl So9SockDomain
{
pub const UNSPEC: Self = Self(0);
pub const IPV4: Self = Self(libc::AF_INET);
pub const IPV6: Self = Self(libc::AF_INET6);
pub const UNIX: Self = Self(libc::AF_UNIX);
#[cfg(any(target_os = "android", target_os = "linux"))]
pub const PACKET: Self = Self(libc::AF_PACKET);
#[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;
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum So9DomainRange
{
DoInets,
DoUnixs,
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))
),
}
}
}