use std::fmt::{Debug, Formatter, Write};
use std::num::NonZeroU16;
use crate::{hci, name_of};
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
#[repr(transparent)]
pub struct LeU(hci::ConnHandle);
impl LeU {
#[inline]
#[must_use]
pub(super) const fn new(cn: hci::ConnHandle) -> Self {
Self(cn)
}
#[inline]
#[must_use]
pub(super) fn chan(self, chan: Cid) -> LeCid {
assert!(chan.is_le());
LeCid { link: self, chan }
}
}
impl From<LeU> for u16 {
#[inline]
fn from(link: LeU) -> Self {
Self::from(link.0)
}
}
impl From<LeU> for hci::ConnHandle {
#[inline]
fn from(link: LeU) -> Self {
link.0
}
}
impl Debug for LeU {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}({:#05X})", name_of!(LeU), u16::from(*self))
}
}
#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[repr(transparent)]
pub struct Cid(NonZeroU16);
impl Cid {
pub(crate) const ATT: Self = Self::fixed(0x0004);
pub(crate) const SIG: Self = Self::fixed(0x0005);
pub(crate) const SMP: Self = Self::fixed(0x0006);
#[inline]
#[must_use]
const fn fixed(v: u16) -> Self {
Self(unsafe { NonZeroU16::new_unchecked(v) })
}
#[inline]
#[must_use]
pub(super) const fn new(v: u16) -> Option<Self> {
match NonZeroU16::new(v) {
Some(nz) => Some(Self(nz)),
None => None,
}
}
#[inline]
#[must_use]
pub(super) const fn is_le(self) -> bool {
matches!(
self.0.get(),
0x0004 | 0x0005 | 0x0006 | 0x0040..=0x007F
)
}
#[inline(always)]
fn write_fmt(self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::ATT => f.write_str("ATT"),
Self::SIG => f.write_str("SIG"),
Self::SMP => f.write_str("SMP"),
_ => write!(f, "{:#06X}", self.0.get()),
}
}
}
impl From<Cid> for u16 {
#[inline]
fn from(cid: Cid) -> Self {
cid.0.get()
}
}
impl Debug for Cid {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(name_of!(Cid))?;
f.write_char('(')?;
self.write_fmt(f)?;
f.write_char(')')
}
}
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
pub struct LeCid {
pub(crate) link: LeU,
pub(crate) chan: Cid,
}
impl Debug for LeCid {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}({:#05X}, ", name_of!(LeCid), u16::from(self.link),)?;
self.chan.write_fmt(f)?;
f.write_char(')')
}
}
crate::impl_display_via_debug! { LeU, Cid, LeCid }