#[cfg(any(test, feature = "generator"))]
use bolero_generator::prelude::*;
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(any(test, feature = "generator"), derive(TypeGenerator))]
#[cfg_attr(kani, derive(kani::Arbitrary))]
pub enum ExplicitCongestionNotification {
NotEct = 0b00,
Ect1 = 0b01,
Ect0 = 0b10,
Ce = 0b11,
}
impl Default for ExplicitCongestionNotification {
#[inline]
fn default() -> Self {
Self::NotEct
}
}
impl ExplicitCongestionNotification {
#[inline]
pub fn new(ecn_field: u8) -> Self {
match ecn_field & 0b11 {
0b00 => ExplicitCongestionNotification::NotEct,
0b01 => ExplicitCongestionNotification::Ect1,
0b10 => ExplicitCongestionNotification::Ect0,
0b11 => ExplicitCongestionNotification::Ce,
_ => unreachable!(),
}
}
#[inline]
pub fn congestion_experienced(self) -> bool {
self == Self::Ce
}
#[inline]
pub fn using_ecn(self) -> bool {
self != Self::NotEct
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new() {
for ecn in &[
ExplicitCongestionNotification::NotEct,
ExplicitCongestionNotification::Ect1,
ExplicitCongestionNotification::Ect0,
ExplicitCongestionNotification::Ce,
] {
assert_eq!(*ecn, ExplicitCongestionNotification::new(*ecn as u8));
}
}
#[test]
fn dscp_markings() {
for i in 0..u8::MAX {
for ecn in &[
ExplicitCongestionNotification::NotEct,
ExplicitCongestionNotification::Ect1,
ExplicitCongestionNotification::Ect0,
ExplicitCongestionNotification::Ce,
] {
assert_eq!(
*ecn,
ExplicitCongestionNotification::new((i << 2) | *ecn as u8)
);
}
}
}
}