#[non_exhaustive]
#[allow(non_camel_case_types)]
#[allow(clippy::upper_case_acronyms)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FrameType {
SETUP,
LEASE,
KEEPALIVE,
REQUEST_RESPONSE,
REQUEST_FNF,
REQUEST_STREAM,
REQUEST_CHANNEL,
REQUEST_N,
CANCEL,
PAYLOAD,
ERROR,
METADATA_PUSH,
RESUME,
RESUME_OK,
EXT,
}
impl FrameType {
pub fn from_value(val: u16) -> Option<FrameType> {
match val {
0x01 => Some(FrameType::SETUP),
0x02 => Some(FrameType::LEASE),
0x03 => Some(FrameType::KEEPALIVE),
0x04 => Some(FrameType::REQUEST_RESPONSE),
0x05 => Some(FrameType::REQUEST_FNF),
0x06 => Some(FrameType::REQUEST_STREAM),
0x07 => Some(FrameType::REQUEST_CHANNEL),
0x08 => Some(FrameType::REQUEST_N),
0x09 => Some(FrameType::CANCEL),
0x0A => Some(FrameType::PAYLOAD),
0x0B => Some(FrameType::ERROR),
0x0C => Some(FrameType::METADATA_PUSH),
0x0D => Some(FrameType::RESUME),
0x0E => Some(FrameType::RESUME_OK),
0x3F => Some(FrameType::EXT),
_ => None,
}
}
pub fn from_bits(bits: u16) -> Option<FrameType> {
match bits >> 10 {
0x01 => Some(FrameType::SETUP),
0x02 => Some(FrameType::LEASE),
0x03 => Some(FrameType::KEEPALIVE),
0x04 => Some(FrameType::REQUEST_RESPONSE),
0x05 => Some(FrameType::REQUEST_FNF),
0x06 => Some(FrameType::REQUEST_STREAM),
0x07 => Some(FrameType::REQUEST_CHANNEL),
0x08 => Some(FrameType::REQUEST_N),
0x09 => Some(FrameType::CANCEL),
0x0A => Some(FrameType::PAYLOAD),
0x0B => Some(FrameType::ERROR),
0x0C => Some(FrameType::METADATA_PUSH),
0x0D => Some(FrameType::RESUME),
0x0E => Some(FrameType::RESUME_OK),
0x3F => Some(FrameType::EXT),
_ => None,
}
}
pub fn value(self) -> u16 {
match self {
FrameType::SETUP => 0x01,
FrameType::LEASE => 0x02,
FrameType::KEEPALIVE => 0x03,
FrameType::REQUEST_RESPONSE => 0x04,
FrameType::REQUEST_FNF => 0x05,
FrameType::REQUEST_STREAM => 0x06,
FrameType::REQUEST_CHANNEL => 0x07,
FrameType::REQUEST_N => 0x08,
FrameType::CANCEL => 0x09,
FrameType::PAYLOAD => 0x0A,
FrameType::ERROR => 0x0B,
FrameType::METADATA_PUSH => 0x0C,
FrameType::RESUME => 0x0D,
FrameType::RESUME_OK => 0x0E,
FrameType::EXT => 0x3F,
}
}
pub fn bits(self) -> u16 {
let val = match self {
FrameType::SETUP => 0x01,
FrameType::LEASE => 0x02,
FrameType::KEEPALIVE => 0x03,
FrameType::REQUEST_RESPONSE => 0x04,
FrameType::REQUEST_FNF => 0x05,
FrameType::REQUEST_STREAM => 0x06,
FrameType::REQUEST_CHANNEL => 0x07,
FrameType::REQUEST_N => 0x08,
FrameType::CANCEL => 0x09,
FrameType::PAYLOAD => 0x0A,
FrameType::ERROR => 0x0B,
FrameType::METADATA_PUSH => 0x0C,
FrameType::RESUME => 0x0D,
FrameType::RESUME_OK => 0x0E,
FrameType::EXT => 0x3F,
};
val << 10
}
}
bitflags! {
pub struct Flags: u16 {
const IGNORE = 0b01_0000_0000;
const METADATA = 0b00_1000_0000;
const FOLLOWS = 0b00_0100_0000;
const RESUME = 0b00_0100_0000;
const RESPOND = 0b00_0100_0000;
const COMPLETE = 0b00_0010_0000;
const LEASE = 0b00_0010_0000;
const NEXT = 0b00_0001_0000;
}
}
impl Flags {
pub fn is_ignore(&self) -> bool {
self.contains(Flags::IGNORE)
}
pub fn is_metadata(&self) -> bool {
self.contains(Flags::METADATA)
}
pub fn is_follows(&self) -> bool {
self.contains(Flags::FOLLOWS)
}
pub fn is_resume(&self) -> bool {
self.contains(Flags::RESUME)
}
pub fn is_respond(&self) -> bool {
self.contains(Flags::RESPOND)
}
pub fn is_complete(&self) -> bool {
self.contains(Flags::COMPLETE)
}
pub fn is_lease(&self) -> bool {
self.contains(Flags::LEASE)
}
pub fn is_next(&self) -> bool {
self.contains(Flags::NEXT)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn from_value() {
assert_eq!(FrameType::from_value(0x01).unwrap(), FrameType::SETUP);
assert_eq!(FrameType::from_value(0x02).unwrap(), FrameType::LEASE);
assert_eq!(FrameType::from_value(0x03).unwrap(), FrameType::KEEPALIVE);
assert_eq!(
FrameType::from_value(0x04).unwrap(),
FrameType::REQUEST_RESPONSE
);
assert_eq!(
FrameType::from_value(0x05).unwrap(),
FrameType::REQUEST_FNF
);
assert_eq!(
FrameType::from_value(0x06).unwrap(),
FrameType::REQUEST_STREAM
);
assert_eq!(
FrameType::from_value(0x07).unwrap(),
FrameType::REQUEST_CHANNEL
);
assert_eq!(FrameType::from_value(0x08).unwrap(), FrameType::REQUEST_N);
assert_eq!(FrameType::from_value(0x09).unwrap(), FrameType::CANCEL);
assert_eq!(FrameType::from_value(0x0A).unwrap(), FrameType::PAYLOAD);
assert_eq!(FrameType::from_value(0x0B).unwrap(), FrameType::ERROR);
assert_eq!(
FrameType::from_value(0x0C).unwrap(),
FrameType::METADATA_PUSH
);
assert_eq!(FrameType::from_value(0x0D).unwrap(), FrameType::RESUME);
assert_eq!(FrameType::from_value(0x0E).unwrap(), FrameType::RESUME_OK);
assert_eq!(FrameType::from_value(0x3F).unwrap(), FrameType::EXT);
assert!(FrameType::from_value(0x00).is_none());
}
#[test]
fn from_bits() {
assert_eq!(
FrameType::from_bits(0x01 << 10).unwrap(),
FrameType::SETUP
);
assert_eq!(
FrameType::from_bits(0x02 << 10).unwrap(),
FrameType::LEASE
);
assert_eq!(
FrameType::from_bits(0x03 << 10).unwrap(),
FrameType::KEEPALIVE
);
assert_eq!(
FrameType::from_bits(0x04 << 10).unwrap(),
FrameType::REQUEST_RESPONSE
);
assert_eq!(
FrameType::from_bits(0x05 << 10).unwrap(),
FrameType::REQUEST_FNF
);
assert_eq!(
FrameType::from_bits(0x06 << 10).unwrap(),
FrameType::REQUEST_STREAM
);
assert_eq!(
FrameType::from_bits(0x07 << 10).unwrap(),
FrameType::REQUEST_CHANNEL
);
assert_eq!(
FrameType::from_bits(0x08 << 10).unwrap(),
FrameType::REQUEST_N
);
assert_eq!(
FrameType::from_bits(0x09 << 10).unwrap(),
FrameType::CANCEL
);
assert_eq!(
FrameType::from_bits(0x0A << 10).unwrap(),
FrameType::PAYLOAD
);
assert_eq!(
FrameType::from_bits(0x0B << 10).unwrap(),
FrameType::ERROR
);
assert_eq!(
FrameType::from_bits(0x0C << 10).unwrap(),
FrameType::METADATA_PUSH
);
assert_eq!(
FrameType::from_bits(0x0D << 10).unwrap(),
FrameType::RESUME
);
assert_eq!(
FrameType::from_bits(0x0E << 10).unwrap(),
FrameType::RESUME_OK
);
assert_eq!(FrameType::from_bits(0x3F << 10).unwrap(), FrameType::EXT);
assert!(FrameType::from_bits(0x00).is_none());
}
#[test]
fn value() {
assert_eq!(FrameType::SETUP.value(), 0x01);
}
#[test]
fn bits() {
assert_eq!(FrameType::SETUP.bits(), 0b0000_0100_0000_0000);
}
}