use core::fmt;
use core::net::{Ipv6Addr, SocketAddrV6};
use super::{Bvll6Error, BIP6_ADDRESS_LENGTH, VMAC_LENGTH};
const IPV6_LENGTH: usize = 16;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Bip6Address {
pub ip: Ipv6Addr,
pub port: u16,
}
impl Bip6Address {
#[must_use]
pub const fn new(ip: Ipv6Addr, port: u16) -> Self {
Self { ip, port }
}
#[must_use]
pub const fn to_octets(self) -> [u8; BIP6_ADDRESS_LENGTH] {
let mut octets = [0; BIP6_ADDRESS_LENGTH];
let (ip, port) = octets.split_at_mut(IPV6_LENGTH);
ip.copy_from_slice(&self.ip.octets());
port.copy_from_slice(&self.port.to_be_bytes());
octets
}
#[must_use]
pub const fn from_octets(octets: [u8; BIP6_ADDRESS_LENGTH]) -> Self {
let mut ip = [0; IPV6_LENGTH];
ip.copy_from_slice(octets.split_at(IPV6_LENGTH).0);
Self {
ip: Ipv6Addr::from_octets(ip),
port: u16::from_be_bytes([octets[IPV6_LENGTH], octets[IPV6_LENGTH + 1]]),
}
}
pub fn from_slice(octets: &[u8]) -> Result<Self, Bvll6Error> {
match <[u8; BIP6_ADDRESS_LENGTH]>::try_from(octets) {
Ok(octets) => Ok(Self::from_octets(octets)),
Err(_) => Err(Bvll6Error::AddressLength {
length: octets.len(),
}),
}
}
}
impl From<SocketAddrV6> for Bip6Address {
fn from(address: SocketAddrV6) -> Self {
Self::new(*address.ip(), address.port())
}
}
impl From<Bip6Address> for SocketAddrV6 {
fn from(address: Bip6Address) -> Self {
SocketAddrV6::new(address.ip, address.port, 0, 0)
}
}
impl fmt::Display for Bip6Address {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[{}]:{}", self.ip, self.port)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Bip6Vmac([u8; VMAC_LENGTH]);
impl Bip6Vmac {
#[must_use]
pub const fn new(octets: [u8; VMAC_LENGTH]) -> Self {
Self(octets)
}
#[must_use]
pub const fn octets(self) -> [u8; VMAC_LENGTH] {
self.0
}
}
impl From<[u8; VMAC_LENGTH]> for Bip6Vmac {
fn from(octets: [u8; VMAC_LENGTH]) -> Self {
Self(octets)
}
}
impl From<Bip6Vmac> for [u8; VMAC_LENGTH] {
fn from(vmac: Bip6Vmac) -> Self {
vmac.0
}
}