use std::fmt::{Debug, Formatter};
use structbuf::{Packer, Unpacker};
#[allow(clippy::exhaustive_enums)]
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum Addr {
Public(RawAddr),
Random(RawAddr),
}
impl Addr {
#[inline]
#[must_use]
pub(super) fn peer(typ: u8, raw: RawAddr) -> Self {
match typ {
0x00 | 0x02 => Self::Public(raw),
0x01 | 0x03 => Self::Random(raw),
_ => unreachable!("unknown peer address type {typ:#04X}"),
}
}
#[inline]
#[must_use]
pub const fn raw(self) -> RawAddr {
match self {
Self::Public(addr) | Self::Random(addr) => addr,
}
}
}
impl Default for Addr {
#[inline]
fn default() -> Self {
Self::Public(RawAddr::default())
}
}
impl burble_crypto::Codec for Addr {
#[inline]
fn pack(&self, p: &mut Packer) {
match *self {
Self::Public(ref addr) => p.u8(0).put(addr.0),
Self::Random(ref addr) => p.u8(1).put(addr.0),
};
}
#[inline]
fn unpack(p: &mut Unpacker) -> Option<Self> {
Some(match (p.u8(), RawAddr::from_le_bytes(p.bytes())) {
(0, addr) => Self::Public(addr),
(1, addr) => Self::Random(addr),
_ => return None,
})
}
}
impl From<Addr> for burble_crypto::Addr {
#[inline]
fn from(a: Addr) -> Self {
let (is_random, raw) = match a {
Addr::Public(addr) => (false, addr.0),
Addr::Random(addr) => (true, addr.0),
};
Self::from_le_bytes(is_random, raw)
}
}
#[derive(Clone, Copy, Default, Eq, Ord, PartialEq, PartialOrd)]
#[repr(transparent)]
pub struct RawAddr([u8; 6]);
impl RawAddr {
#[inline(always)]
#[must_use]
pub const fn from_le_bytes(v: [u8; 6]) -> Self {
Self(v)
}
#[inline(always)]
#[must_use]
pub const fn as_le_bytes(self) -> [u8; 6] {
self.0
}
}
impl AsRef<[u8]> for RawAddr {
#[inline(always)]
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}
impl Debug for RawAddr {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}",
self.0[5], self.0[4], self.0[3], self.0[2], self.0[1], self.0[0]
)
}
}
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
#[repr(transparent)]
pub struct TxPower(i8);
impl TxPower {
pub(crate) const MAX: i8 = 20;
pub(crate) const NONE: i8 = 0x7F;
#[inline(always)]
#[must_use]
pub const fn new(v: i8) -> Self {
Self(v)
}
}
impl Default for TxPower {
#[inline(always)]
fn default() -> Self {
Self(Self::MAX)
}
}
impl From<TxPower> for i8 {
#[inline(always)]
fn from(p: TxPower) -> Self {
p.0
}
}
crate::impl_display_via_debug! { Addr, RawAddr }