#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PayloadLen {
Standard(u8),
Extended1(u16),
Extended2(u64),
}
impl PayloadLen {
#[inline]
pub const fn from_num(n: u64) -> Self {
if n < 126 {
PayloadLen::Standard(n as u8)
} else if n < 65536 {
PayloadLen::Extended1(n as u16)
} else {
PayloadLen::Extended2(n)
}
}
#[inline]
pub const fn to_num(self) -> u64 {
use PayloadLen::*;
match self {
Standard(v) => v as u64,
Extended1(v) => v as u64,
Extended2(v) => v,
}
}
#[inline]
pub const fn from_flag(b: u8) -> Self {
match b & 0x7f {
126 => PayloadLen::Extended1(0),
127 => PayloadLen::Extended2(0),
b => PayloadLen::Standard(b),
}
}
#[inline]
pub const fn to_flag(&self) -> u8 {
use PayloadLen::*;
match self {
Standard(b) => *b,
Extended1(_) => 126,
Extended2(_) => 127,
}
}
#[inline]
pub const fn from_byte2(buf: [u8; 2]) -> Self { PayloadLen::Extended1(u16::from_be_bytes(buf)) }
#[inline]
pub const fn from_byte8(buf: [u8; 8]) -> Self { PayloadLen::Extended2(u64::from_be_bytes(buf)) }
#[inline]
pub const fn to_u8(&self) -> u8 {
match self {
PayloadLen::Standard(v) => *v,
_ => unreachable!(),
}
}
#[inline]
pub const fn to_u16(&self) -> u16 {
match self {
PayloadLen::Extended1(v) => *v,
_ => unreachable!(),
}
}
#[inline]
pub const fn to_u64(&self) -> u64 {
match self {
PayloadLen::Extended2(v) => *v,
_ => unreachable!(),
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn standard() {
for v in 0..=125_u8 {
let a = PayloadLen::from_flag(v);
let b = PayloadLen::from_num(v as u64);
assert_eq!(a.to_flag(), v);
assert_eq!(a.to_num(), b.to_num());
}
}
#[test]
fn extend1() {
for v in 126..=65535_u16 {
let a = PayloadLen::from_num(v as u64);
let b = PayloadLen::from_byte2(v.to_be_bytes());
assert_eq!(a.to_flag(), 126_u8);
assert_eq!(a.to_num(), b.to_num());
}
}
#[test]
fn extend2() {
for v in 65536..=100000_u64 {
let a = PayloadLen::from_num(v);
let b = PayloadLen::from_byte8(v.to_be_bytes());
assert_eq!(a.to_flag(), 127_u8);
assert_eq!(a.to_num(), b.to_num());
}
}
}