#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive(Copy, Clone, PartialEq, Debug)]
pub(crate) struct COwn(u8);
impl COwn {
pub(crate) const MAX_SLICE_LEN: usize = 1;
pub(crate) const GENERATABLE_VALUES: usize = 48;
pub(crate) fn not_in_iter(iterator: impl Iterator<Item = Self>) -> Self {
assert!(
iterator
.size_hint()
.1
.is_some_and(|v| v < Self::GENERATABLE_VALUES),
"Too many slots to reliably assign connection identifier"
);
let mut seen_pos = 0u32;
let mut seen_neg = 0u32;
for i in iterator {
let major = i.0 >> 5;
let target = if major == 0 {
&mut seen_pos
} else {
&mut seen_neg
};
*target |= 1 << (i.0 & 0x1f);
}
let pos_to = seen_pos.trailing_ones();
if pos_to < 24 {
#[expect(
clippy::cast_possible_truncation,
reason = "ensured by the GENERATABLE_VALUES check"
)]
return Self(pos_to as u8);
}
let neg_to = seen_neg.trailing_ones();
if neg_to < 24 {
#[expect(
clippy::cast_possible_truncation,
reason = "ensured by the GENERATABLE_VALUES check"
)]
return Self(0x20 | neg_to as u8);
}
unreachable!("Iterator is not long enough to set this many bits.");
}
pub(crate) fn from_kid(kid: &[u8]) -> Option<Self> {
match kid {
[first] if *first <= 0x17 || (*first >= 0x20 && *first <= 0x37) => Some(Self(*first)),
_ => None,
}
}
pub(crate) fn as_slice(&self) -> &[u8] {
core::slice::from_ref(&self.0)
}
}
impl From<COwn> for lakers::ConnId {
fn from(cown: COwn) -> Self {
lakers::ConnId::from_slice(cown.as_slice())
.expect("ConnId is always big enough for at least COwn")
}
}