//! Various network types

use core::fmt;

// pub mod ip_addr;
pub mod net_value;
// pub mod socket_addr;
pub mod subnet_addr;

pub use net_value::{NetValue, NetValueImpl};

/// Describes a hardware MAC address
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
// #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(transparent)]
pub struct MacAddress([u8; 6]);

impl MacAddress {
    /// A broadcast MAC address
    pub const BROADCAST: Self = Self([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]);
    /// An unspecified MAC address
    pub const UNSPECIFIED: Self = Self([0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);

    /// Returns the bytes comprising this MAC address
    pub const fn octets(self) -> [u8; 6] {
        self.0
    }
}

impl From<[u8; 6]> for MacAddress {
    fn from(value: [u8; 6]) -> Self {
        Self(value)
    }
}

impl From<MacAddress> for [u8; 6] {
    fn from(value: MacAddress) -> Self {
        value.0
    }
}

impl fmt::Display for MacAddress {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        for (i, octet) in self.0.into_iter().enumerate() {
            if i != 0 {
                write!(f, ":")?;
            }
            write!(f, "{octet:02X}")?;
        }

        Ok(())
    }
}

abi_serde::impl_newtype_serde!(MacAddress);

/// Local socket address
#[derive(Clone, Debug, PartialEq)]
pub enum LocalSocketAddress<'a> {
    /// Describes a named socket bound to a specific path
    Path(&'a str),
    /// Describes an anonymous socket
    Anonymous(u64),
}
abi_serde::impl_enum1_serde!(LocalSocketAddress<'de>: [
    Path => 1,
    Anonymous => 2,
]);
