ding 0.0.0

A DNS client and server library
Documentation
use alloc::boxed::Box;
use anyhow::Result;
use core::{fmt, pin::Pin};
use futures::{AsyncRead, AsyncWrite};

pub trait Socket: AsyncRead + AsyncWrite + 'static {
    fn connect(address: SocketAddr) -> Result<Pin<Box<dyn Socket + Send>>>
    where
        Self: Sized;
}

/// Internal IPv4 address representation
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Ipv4Addr(pub [u16; 4]);

impl Ipv4Addr {
    pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Self {
        Self([a as u16, b as u16, c as u16, d as u16])
    }

    pub const fn octets(&self) -> [u8; 4] {
        [
            self.0[0] as u8,
            self.0[1] as u8,
            self.0[2] as u8,
            self.0[3] as u8,
        ]
    }

    pub fn from_bytes(bytes: [u8; 4]) -> Self {
        Self([
            bytes[0] as u16,
            bytes[1] as u16,
            bytes[2] as u16,
            bytes[3] as u16,
        ])
    }
}

impl fmt::Display for Ipv4Addr {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let octets = self.octets();
        write!(f, "{}.{}.{}.{}", octets[0], octets[1], octets[2], octets[3])
    }
}

/// Internal IPv6 address representation
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Ipv6Addr(pub [u16; 8]);

impl Ipv6Addr {
    pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Self {
        Self([a, b, c, d, e, f, g, h])
    }

    pub const fn segments(&self) -> [u16; 8] {
        self.0
    }

    pub fn octets(&self) -> [u8; 16] {
        let mut octets = [0u8; 16];
        for (i, &segment) in self.0.iter().enumerate() {
            octets[i * 2] = (segment >> 8) as u8;
            octets[i * 2 + 1] = (segment & 0xff) as u8;
        }
        octets
    }
}

/// Internal IP address enum
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum IpAddr {
    V4(Ipv4Addr),
    V6(Ipv6Addr),
}

/// Internal socket address
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct SocketAddr {
    ip: IpAddr,
    port: u16,
}

impl SocketAddr {
    pub const fn new(ip: IpAddr, port: u16) -> Self {
        Self { ip, port }
    }

    pub const fn v4(ip: Ipv4Addr, port: u16) -> Self {
        Self {
            ip: IpAddr::V4(ip),
            port,
        }
    }

    pub const fn v6(ip: Ipv6Addr, port: u16) -> Self {
        Self {
            ip: IpAddr::V6(ip),
            port,
        }
    }

    pub const fn ip(&self) -> IpAddr {
        self.ip
    }

    pub const fn port(&self) -> u16 {
        self.port
    }
}