use std::{fmt, ops::RangeInclusive};
use fixedbitset::{FixedBitSet, IndexRange};
use nix::errno::Errno;
use serde::{ser::SerializeSeq, Serialize, Serializer};
pub type Port = u16;
const PORT_SET_CAPACITY: usize = 0x10000;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PortRange(Option<RangeInclusive<Port>>);
impl PortRange {
pub fn full() -> Self {
Self(None)
}
pub fn single(port: Port) -> Self {
Self(Some(port..=port))
}
pub fn new(start: Port, end: Port) -> Self {
if start == 0 && end == Port::MAX {
Self(None)
} else if start <= end {
Self(Some(start..=end))
} else {
Self(Some(end..=start))
}
}
pub fn is_full(&self) -> bool {
self.0.is_none()
}
pub fn port_start(&self) -> Port {
self.0.as_ref().map_or(0, |r| *r.start())
}
pub fn port_end(&self) -> Port {
self.0.as_ref().map_or(Port::MAX, |r| *r.end())
}
}
impl fmt::Display for PortRange {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.0 {
None => write!(f, "0-65535"),
Some(r) if r.start() == r.end() => write!(f, "{}", r.start()),
Some(r) => write!(f, "{}-{}", r.start(), r.end()),
}
}
}
impl Serialize for PortRange {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match &self.0 {
None => {
let mut seq = serializer.serialize_seq(Some(2))?;
seq.serialize_element(&0u16)?;
seq.serialize_element(&Port::MAX)?;
seq.end()
}
Some(r) if r.start() == r.end() => serializer.serialize_u16(*r.start()),
Some(r) => {
let mut seq = serializer.serialize_seq(Some(2))?;
seq.serialize_element(r.start())?;
seq.serialize_element(r.end())?;
seq.end()
}
}
}
}
impl IndexRange<usize> for PortRange {
fn start(&self) -> Option<usize> {
self.0.as_ref().map(|r| usize::from(*r.start()))
}
fn end(&self) -> Option<usize> {
self.0
.as_ref()
.map(|r| usize::from(*r.end()).saturating_add(1))
}
}
impl IndexRange<usize> for &PortRange {
fn start(&self) -> Option<usize> {
(**self).start()
}
fn end(&self) -> Option<usize> {
(**self).end()
}
}
#[derive(Clone, Debug)]
pub enum PortSet {
None,
Full,
One(Port),
Range(PortRange),
Set(FixedBitSet),
}
impl PortSet {
pub fn full() -> Self {
Self::Full
}
pub fn empty() -> Self {
Self::None
}
pub fn is_full(&self) -> bool {
match self {
Self::Full => true,
Self::Range(range) => range.is_full(),
Self::Set(set) => set.len() >= PORT_SET_CAPACITY && set.is_full(),
_ => false,
}
}
pub fn is_clear(&self) -> bool {
match self {
Self::None => true,
Self::Set(set) => set.is_clear(),
_ => false,
}
}
pub fn contains(&self, port: Port) -> bool {
match self {
Self::None => false,
Self::Full => true,
Self::One(p) => *p == port,
Self::Range(r) => port >= r.port_start() && port <= r.port_end(),
Self::Set(set) => set.contains(usize::from(port)),
}
}
pub fn insert(&mut self, port: Port) {
match self {
Self::Full => {}
Self::None => *self = Self::One(port),
Self::One(existing) if *existing == port => {}
Self::One(existing) => {
let (lower, upper) = if port < *existing {
(port, *existing)
} else {
(*existing, port)
};
if upper == lower.saturating_add(1) {
*self = Self::Range(PortRange::new(lower, upper));
} else {
let capacity = usize::from(upper).saturating_add(1);
let mut set = FixedBitSet::with_capacity(capacity);
set.insert(lower.into());
set.insert(upper.into());
*self = Self::Set(set);
}
}
Self::Range(range) if port >= range.port_start() && port <= range.port_end() => {}
Self::Range(range) => {
let range_start = range.port_start();
let range_end = range.port_end();
if range_start.checked_sub(1) == Some(port) {
let new_range = PortRange::new(port, range_end);
if new_range.is_full() {
*self = Self::Full;
} else {
*self = Self::Range(new_range);
}
} else if range_end.checked_add(1) == Some(port) {
let new_range = PortRange::new(range_start, port);
if new_range.is_full() {
*self = Self::Full;
} else {
*self = Self::Range(new_range);
}
} else {
let capacity = port.max(range_end).saturating_add(1).into();
let mut set = FixedBitSet::with_capacity(capacity);
set.insert_range(range.clone());
set.insert(port.into());
*self = Self::Set(set);
}
}
Self::Set(set) => {
let index = usize::from(port);
set.grow(index.saturating_add(1));
set.insert(index);
self.compact();
}
}
}
pub fn insert_range(&mut self, range: PortRange) {
if range.is_full() {
*self = Self::Full;
return;
}
match self {
Self::Full => {}
Self::None => {
if range.port_start() == range.port_end() {
*self = Self::One(range.port_start());
} else {
*self = Self::Range(range);
}
}
Self::One(existing) => {
let existing = *existing;
let new_start = range.port_start();
let new_end = range.port_end();
if existing >= new_start && existing <= new_end {
if new_start == new_end {
} else {
*self = Self::Range(range);
}
} else if new_start.checked_sub(1) == Some(existing) {
*self = Self::Range(PortRange::new(existing, new_end));
} else if new_end.checked_add(1) == Some(existing) {
*self = Self::Range(PortRange::new(new_start, existing));
} else {
let capacity = usize::from(existing.max(new_end)).saturating_add(1);
let mut set = FixedBitSet::with_capacity(capacity);
set.insert(usize::from(existing));
if let Some(end) = IndexRange::end(&range) {
set.grow(end);
}
set.insert_range(range);
*self = Self::Set(set);
}
}
Self::Range(current) => {
let cur_start = current.port_start();
let cur_end = current.port_end();
let new_start = range.port_start();
let new_end = range.port_end();
let may_merge = new_end >= cur_start.saturating_sub(1)
&& new_start <= cur_end.saturating_add(1);
if may_merge {
let merged = PortRange::new(cur_start.min(new_start), cur_end.max(new_end));
if merged.is_full() {
*self = Self::Full;
} else {
*self = Self::Range(merged);
}
} else {
let capacity = cur_end.max(new_end).saturating_add(1).into();
let mut set = FixedBitSet::with_capacity(capacity);
set.insert_range(current.clone());
if let Some(end) = IndexRange::end(&range) {
set.grow(end);
}
set.insert_range(range);
*self = Self::Set(set);
}
}
Self::Set(set) => {
if let Some(end) = IndexRange::end(&range) {
set.grow(end);
}
set.insert_range(range);
self.compact();
}
}
}
pub fn remove_range(&mut self, range: PortRange) {
let remove_start = range.port_start();
let remove_end = range.port_end();
match self {
Self::None => {}
Self::Full => {
if remove_start == 0 && remove_end == Port::MAX {
*self = Self::None;
} else if remove_start == 0 {
let new_start = remove_end.saturating_add(1);
if new_start == Port::MAX {
*self = Self::One(Port::MAX);
} else {
*self = Self::Range(PortRange::new(new_start, Port::MAX));
}
} else if remove_end == Port::MAX {
let new_end = remove_start.saturating_sub(1);
if new_end == 0 {
*self = Self::One(0);
} else {
*self = Self::Range(PortRange::new(0, new_end));
}
} else {
let mut set = FixedBitSet::with_capacity(PORT_SET_CAPACITY);
set.insert_range(..);
set.remove_range(range);
*self = Self::Set(set);
}
}
Self::One(existing) => {
if *existing >= remove_start && *existing <= remove_end {
*self = Self::None;
}
}
Self::Range(current) => {
let cur_start = current.port_start();
let cur_end = current.port_end();
if remove_start <= cur_start && remove_end >= cur_end {
*self = Self::None;
} else if remove_end < cur_start || remove_start > cur_end {
} else if remove_start <= cur_start {
let new_start = remove_end.saturating_add(1);
if new_start == cur_end {
*self = Self::One(cur_end);
} else {
*self = Self::Range(PortRange::new(new_start, cur_end));
}
} else if remove_end >= cur_end {
let new_end = remove_start.saturating_sub(1);
if cur_start == new_end {
*self = Self::One(cur_start);
} else {
*self = Self::Range(PortRange::new(cur_start, new_end));
}
} else {
let capacity = cur_end.saturating_add(1).into();
let mut set = FixedBitSet::with_capacity(capacity);
set.insert_range(current.clone());
set.remove_range(range);
*self = Self::Set(set);
}
}
Self::Set(set) => {
set.remove_range(range);
self.compact();
}
}
}
pub fn union_with(&mut self, other: &PortSet) {
if self.is_full() || other.is_full() {
*self = Self::Full;
return;
}
match other {
Self::None => {}
Self::Full => unreachable!(),
Self::One(port) => self.insert(*port),
Self::Range(range) => self.insert_range(range.clone()),
Self::Set(other_set) => match self {
Self::Set(ref mut self_set) => {
self_set.union_with(other_set);
self.compact();
}
_ => {
let mut set = FixedBitSet::from(std::mem::replace(self, Self::None));
set.union_with(other_set);
*self = Self::Set(set);
self.compact();
}
},
}
}
pub fn difference_with(&mut self, other: &PortSet) {
if self.is_clear() || other.is_clear() {
return;
}
if other.is_full() {
*self = Self::None;
return;
}
match other {
Self::None | Self::Full => {}
Self::One(port) => self.remove_range(PortRange::single(*port)),
Self::Range(range) => self.remove_range(range.clone()),
Self::Set(other_set) => match self {
Self::Set(ref mut self_set) => {
self_set.difference_with(other_set);
self.compact();
}
_ => {
let mut set = FixedBitSet::from(std::mem::replace(self, Self::None));
set.difference_with(other_set);
*self = Self::Set(set);
self.compact();
}
},
}
}
pub fn ones(&self) -> PortSetOnes<'_> {
match self {
Self::None => PortSetOnes::None,
Self::Full => PortSetOnes::Full,
Self::One(port) => PortSetOnes::One(*port),
Self::Range(range) => PortSetOnes::Range(range.clone()),
Self::Set(set) => PortSetOnes::Set(set.ones()),
}
}
pub fn count_ones<T: IndexRange<usize>>(&self, range: T) -> usize {
match self {
Self::None => 0,
Self::Full => {
let start = range.start().unwrap_or(0);
let end = range.end().unwrap_or(PORT_SET_CAPACITY);
end.saturating_sub(start)
}
Self::One(port) => {
let port = usize::from(*port);
let start = range.start().unwrap_or(0);
let end = range.end().unwrap_or(PORT_SET_CAPACITY);
usize::from(port >= start && port < end)
}
Self::Range(self_range) => {
let range_start = usize::from(self_range.port_start());
let range_end = usize::from(self_range.port_end());
let start = range.start().unwrap_or(0).max(range_start);
let end = range
.end()
.unwrap_or(PORT_SET_CAPACITY)
.min(range_end.saturating_add(1));
end.saturating_sub(start)
}
Self::Set(set) => set.count_ones(range),
}
}
pub fn clear(&mut self) {
*self = Self::None;
}
fn compact(&mut self) {
let set = match self {
Self::Set(set) => set,
_ => return,
};
if set.is_clear() {
*self = Self::None;
return;
}
if set.len() >= PORT_SET_CAPACITY && set.is_full() {
*self = Self::Full;
return;
}
let first = match set.minimum() {
Some(first) => first,
Option::None => return,
};
let last = match set.maximum() {
Some(last) => last,
Option::None => return,
};
let count = set.count_ones(..);
if count == 1 {
#[expect(clippy::cast_possible_truncation)]
{
*self = Self::One(first as Port);
}
} else if count == (last.saturating_sub(first)).saturating_add(1) {
#[expect(clippy::cast_possible_truncation)]
{
*self = Self::Range(PortRange::new(first as Port, last as Port));
}
}
}
}
impl From<PortSet> for FixedBitSet {
fn from(port_set: PortSet) -> Self {
match port_set {
PortSet::None => Self::new(),
PortSet::Full => {
let mut set = Self::with_capacity(PORT_SET_CAPACITY);
set.insert_range(..);
set
}
PortSet::One(port) => {
let index = usize::from(port);
let mut set = Self::with_capacity(index.saturating_add(1));
set.insert(index);
set
}
PortSet::Range(range) => {
let capacity = usize::from(range.port_end()).saturating_add(1);
let mut set = Self::with_capacity(capacity);
set.insert_range(range);
set
}
PortSet::Set(set) => set,
}
}
}
impl PartialEq for PortSet {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::None, Self::None) | (Self::Full, Self::Full) => true,
(Self::One(left), Self::One(right)) => left == right,
(Self::Range(left), Self::Range(right)) => left == right,
(Self::Set(left), Self::Set(right)) => left == right,
(Self::None, _) | (_, Self::None) => self.is_clear() && other.is_clear(),
(Self::Full, _) | (_, Self::Full) => self.is_full() && other.is_full(),
(Self::One(port), Self::Range(range)) | (Self::Range(range), Self::One(port)) => {
range.port_start() == *port && range.port_end() == *port
}
(Self::One(port), Self::Set(set)) | (Self::Set(set), Self::One(port)) => {
set.count_ones(..) == 1 && set.contains(usize::from(*port))
}
(Self::Range(range), Self::Set(set)) | (Self::Set(set), Self::Range(range)) => {
let range_start = usize::from(range.port_start());
let range_end = usize::from(range.port_end());
let expected_count = (range_end.saturating_sub(range_start)).saturating_add(1);
let count_end = range_end.saturating_add(1);
set.count_ones(..) == expected_count
&& set.contains(range_start)
&& set.contains(range_end)
&& set.count_ones(range_start..count_end) == expected_count
}
}
}
}
impl Eq for PortSet {}
impl fmt::Display for PortSet {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::None => Ok(()),
Self::Full => write!(f, "0-65535"),
Self::One(port) => write!(f, "{port}"),
Self::Range(range) => write!(f, "{range}"),
Self::Set(set) => {
let mut first = true;
let mut iter = set.ones().peekable();
while let Some(start) = iter.next() {
let mut end = start;
while iter.peek() == Some(&end.saturating_add(1)) {
end = match iter.next() {
Some(val) => val,
Option::None => break,
};
}
if !first {
write!(f, ",")?;
}
first = false;
if start == end {
write!(f, "{start}")?;
} else {
write!(f, "{start}-{end}")?;
}
}
Ok(())
}
}
}
}
impl Serialize for PortSet {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
enum PortSetElement {
Port(u16),
Range(u16, u16),
}
match self {
Self::None => {
let seq = serializer.serialize_seq(Some(0))?;
seq.end()
}
Self::Full => PortRange::full().serialize(serializer),
Self::One(port) => serializer.serialize_u16(*port),
Self::Range(range) => range.serialize(serializer),
Self::Set(set) => {
let mut iter = set.ones().peekable();
let mut elements: Vec<PortSetElement> = Vec::new();
while let Some(start) = iter.next() {
let mut end = start;
while iter.peek() == Some(&end.saturating_add(1)) {
end = match iter.next() {
Some(val) => val,
Option::None => break,
};
}
#[expect(clippy::cast_possible_truncation)]
if start == end {
elements.push(PortSetElement::Port(start as u16));
} else {
elements.push(PortSetElement::Range(start as u16, end as u16));
}
}
let mut seq = serializer.serialize_seq(Some(elements.len()))?;
for elem in &elements {
match elem {
PortSetElement::Port(p) => seq.serialize_element(p)?,
PortSetElement::Range(lo, hi) => {
seq.serialize_element(&[*lo, *hi])?;
}
}
}
seq.end()
}
}
}
}
impl From<Port> for PortSet {
fn from(port: Port) -> Self {
Self::One(port)
}
}
impl From<PortRange> for PortSet {
fn from(range: PortRange) -> Self {
if range.is_full() {
Self::Full
} else {
Self::Range(range)
}
}
}
pub enum PortSetOnes<'a> {
None,
Full,
One(Port),
Range(PortRange),
Set(fixedbitset::Ones<'a>),
}
impl Iterator for PortSetOnes<'_> {
type Item = usize;
fn next(&mut self) -> Option<usize> {
match self {
Self::None => Option::None,
Self::Full => {
let range = PortRange::new(0, Port::MAX);
*self = Self::Range(range);
self.next()
}
Self::One(port) => {
let val = usize::from(*port);
*self = Self::None;
Some(val)
}
Self::Range(range) => {
let start = range.port_start();
let end = range.port_end();
if start <= end {
let val = usize::from(start);
if start == end {
*self = Self::None;
} else {
*self = Self::Range(PortRange::new(start.saturating_add(1), end));
}
Some(val)
} else {
Option::None
}
}
Self::Set(ref mut iter) => iter.next(),
}
}
}
pub fn parse_port_set(input: &str) -> Result<PortSet, Errno> {
if input.is_empty() {
return Err(Errno::EINVAL);
}
let mut set = PortSet::empty();
for part in input.split(',') {
set.insert_range(parse_port_range(part)?);
}
Ok(set)
}
pub fn parse_port_range(input: &str) -> Result<PortRange, Errno> {
let mut split = input.splitn(2, '-');
let port0 = split.next().ok_or(Errno::EINVAL)?;
let port0 = port0.parse::<Port>().or(Err(Errno::EINVAL))?;
if let Some(port1) = split.next() {
let port1 = port1.parse::<Port>().or(Err(Errno::EINVAL))?;
Ok(PortRange::new(port0, port1))
} else {
Ok(PortRange::single(port0))
}
}
#[cfg(test)]
mod tests {
use super::*;
macro_rules! ensure {
($cond:expr) => {
if !($cond) {
eprintln!("ensure failed at {}:{}", file!(), line!());
return Err(Errno::EINVAL);
}
};
}
macro_rules! ensure_eq {
($a:expr, $b:expr) => {
if ($a) != ($b) {
eprintln!("ensure_eq failed at {}:{}", file!(), line!());
return Err(Errno::EINVAL);
}
};
}
fn portset_from_ports(ports: &[Port]) -> PortSet {
let mut set = PortSet::empty();
for &port in ports {
set.insert(port);
}
set
}
fn portset_from_ranges(ranges: &[RangeInclusive<Port>]) -> PortSet {
let mut set = PortSet::empty();
for range in ranges {
set.insert_range(PortRange::new(*range.start(), *range.end()));
}
set
}
#[test]
fn test_port_range_1() -> Result<(), Errno> {
let r = PortRange::full();
ensure!(r.is_full());
ensure_eq!(r.port_start(), 0);
ensure_eq!(r.port_end(), Port::MAX);
ensure_eq!(format!("{r}"), "0-65535");
Ok(())
}
#[test]
fn test_port_range_2() -> Result<(), Errno> {
let r = PortRange::single(80);
ensure!(!r.is_full());
ensure_eq!(r.port_start(), 80);
ensure_eq!(r.port_end(), 80);
ensure_eq!(format!("{r}"), "80");
Ok(())
}
#[test]
fn test_port_range_3() -> Result<(), Errno> {
let r = PortRange::single(0);
ensure_eq!(r.port_start(), 0);
ensure_eq!(r.port_end(), 0);
ensure_eq!(format!("{r}"), "0");
Ok(())
}
#[test]
fn test_port_range_4() -> Result<(), Errno> {
let r = PortRange::single(65535);
ensure_eq!(format!("{r}"), "65535");
Ok(())
}
#[test]
fn test_port_range_5() -> Result<(), Errno> {
let r = PortRange::new(80, 443);
ensure!(!r.is_full());
ensure_eq!(r.port_start(), 80);
ensure_eq!(r.port_end(), 443);
ensure_eq!(format!("{r}"), "80-443");
Ok(())
}
#[test]
fn test_port_range_6() -> Result<(), Errno> {
let r = PortRange::new(443, 80);
ensure_eq!(r.port_start(), 80);
ensure_eq!(r.port_end(), 443);
Ok(())
}
#[test]
fn test_port_range_7() -> Result<(), Errno> {
let r = PortRange::new(0, Port::MAX);
ensure!(r.is_full());
Ok(())
}
#[test]
fn test_port_range_8() -> Result<(), Errno> {
ensure!(PortRange::full().is_full());
ensure!(PortRange::new(0, 65535).is_full());
ensure!(!PortRange::single(80).is_full());
ensure!(!PortRange::new(0, 65534).is_full());
Ok(())
}
#[test]
fn test_port_range_9() -> Result<(), Errno> {
ensure_eq!(PortRange::full().port_start(), 0);
ensure_eq!(PortRange::single(443).port_start(), 443);
ensure_eq!(PortRange::new(1024, 2048).port_start(), 1024);
Ok(())
}
#[test]
fn test_port_range_10() -> Result<(), Errno> {
ensure_eq!(PortRange::full().port_end(), Port::MAX);
ensure_eq!(PortRange::single(443).port_end(), 443);
ensure_eq!(PortRange::new(1024, 2048).port_end(), 2048);
Ok(())
}
#[test]
fn test_port_range_11() -> Result<(), Errno> {
let r = PortRange::full();
ensure!(r.is_full());
ensure_eq!(r.port_start(), 0);
ensure_eq!(r.port_end(), Port::MAX);
Ok(())
}
#[test]
fn test_port_range_12() -> Result<(), Errno> {
let r = PortRange::single(80);
ensure!(!r.is_full());
ensure_eq!(r.port_start(), 80);
ensure_eq!(r.port_end(), 80);
Ok(())
}
#[test]
fn test_port_range_13() -> Result<(), Errno> {
let r = PortRange::new(1024, 65535);
ensure!(!r.is_full());
ensure_eq!(r.port_start(), 1024);
ensure_eq!(r.port_end(), 65535);
Ok(())
}
#[test]
fn test_port_range_14() -> Result<(), Errno> {
ensure!(PortRange::new(0, Port::MAX).is_full());
Ok(())
}
#[test]
fn test_port_range_15() -> Result<(), Errno> {
let r = PortRange::new(100, 50);
ensure_eq!(r.port_start(), 50);
ensure_eq!(r.port_end(), 100);
Ok(())
}
#[test]
fn test_port_range_16() -> Result<(), Errno> {
let r = PortRange::single(80);
ensure_eq!(IndexRange::start(&r), Some(80));
ensure_eq!(IndexRange::end(&r), Some(81));
Ok(())
}
#[test]
fn test_port_range_17() -> Result<(), Errno> {
let r = PortRange::new(1024, 65535);
ensure_eq!(IndexRange::start(&r), Some(1024));
ensure_eq!(IndexRange::end(&r), Some(65536));
Ok(())
}
#[test]
fn test_port_range_18() -> Result<(), Errno> {
let r = PortRange::full();
ensure_eq!(IndexRange::start(&r), None);
ensure_eq!(IndexRange::end(&r), None);
Ok(())
}
#[test]
fn test_port_range_19() -> Result<(), Errno> {
let r = PortRange::single(443);
let r_ref = &r;
ensure_eq!(IndexRange::start(r_ref), Some(443));
ensure_eq!(IndexRange::end(r_ref), Some(444));
Ok(())
}
#[test]
fn test_port_set_1() -> Result<(), Errno> {
ensure_eq!(format!("{}", PortRange::full()), "0-65535");
ensure_eq!(format!("{}", PortRange::single(80)), "80");
ensure_eq!(format!("{}", PortRange::new(80, 443)), "80-443");
Ok(())
}
#[test]
fn test_port_set_2() -> Result<(), Errno> {
let s = PortSet::full();
ensure!(s.is_full());
ensure!(!s.is_clear());
ensure_eq!(format!("{s}"), "0-65535");
Ok(())
}
#[test]
fn test_port_set_3() -> Result<(), Errno> {
ensure!(PortSet::full().is_full());
ensure!(!PortSet::empty().is_full());
ensure!(!PortSet::from(80u16).is_full());
ensure!(PortSet::from(PortRange::full()).is_full());
Ok(())
}
#[test]
fn test_port_set_4() -> Result<(), Errno> {
ensure_eq!(format!("{}", PortSet::empty()), "");
ensure_eq!(format!("{}", PortSet::full()), "0-65535");
ensure_eq!(format!("{}", PortSet::from(80u16)), "80");
ensure_eq!(
format!("{}", PortSet::from(PortRange::new(80, 90))),
"80-90"
);
Ok(())
}
#[test]
fn test_port_set_5() -> Result<(), Errno> {
let mut s = PortSet::empty();
s.insert(80);
s.insert(443);
ensure_eq!(format!("{s}"), "80,443");
Ok(())
}
#[test]
fn test_port_set_6() -> Result<(), Errno> {
let s = PortSet::empty();
ensure!(s.is_clear());
ensure!(!s.is_full());
ensure!(!s.contains(0));
ensure_eq!(s.count_ones(..), 0);
Ok(())
}
#[test]
fn test_port_set_7() -> Result<(), Errno> {
ensure!(PortSet::empty().is_clear());
ensure!(!PortSet::full().is_clear());
ensure!(!PortSet::from(80u16).is_clear());
Ok(())
}
#[test]
fn test_port_set_8() -> Result<(), Errno> {
ensure!(!PortSet::empty().contains(0));
ensure!(PortSet::full().contains(0));
ensure!(PortSet::full().contains(65535));
Ok(())
}
#[test]
fn test_port_set_9() -> Result<(), Errno> {
let s: PortSet = 80u16.into();
ensure!(s.contains(80));
ensure!(!s.contains(79));
ensure!(!s.contains(81));
Ok(())
}
#[test]
fn test_port_set_10() -> Result<(), Errno> {
let s = PortSet::from(PortRange::new(80, 90));
for p in 80..=90 {
ensure!(s.contains(p));
}
ensure!(!s.contains(79));
ensure!(!s.contains(91));
Ok(())
}
#[test]
fn test_port_set_11() -> Result<(), Errno> {
let mut s = PortSet::empty();
s.insert(80);
ensure!(s.contains(80));
ensure!(!s.contains(81));
Ok(())
}
#[test]
fn test_port_set_12() -> Result<(), Errno> {
let mut s = PortSet::empty();
s.insert(80);
s.insert(81);
ensure!(matches!(s, PortSet::Range(_)));
ensure_eq!(s.count_ones(..), 2);
Ok(())
}
#[test]
fn test_port_set_13() -> Result<(), Errno> {
let mut s = PortSet::full();
s.insert(80);
ensure!(s.is_full());
Ok(())
}
#[test]
fn test_port_set_14() -> Result<(), Errno> {
let mut s = PortSet::empty();
s.insert_range(PortRange::new(80, 90));
ensure_eq!(s.count_ones(..), 11);
ensure!(s.contains(80));
ensure!(s.contains(90));
ensure!(!s.contains(91));
Ok(())
}
#[test]
fn test_port_set_15() -> Result<(), Errno> {
let mut s = PortSet::empty();
s.insert_range(PortRange::full());
ensure!(s.is_full());
Ok(())
}
#[test]
fn test_port_set_16() -> Result<(), Errno> {
let mut s = PortSet::full();
s.insert_range(PortRange::new(80, 90));
ensure!(s.is_full());
Ok(())
}
#[test]
fn test_port_set_17() -> Result<(), Errno> {
let mut s = PortSet::full();
s.remove_range(PortRange::single(80));
ensure!(!s.contains(80));
ensure!(s.contains(79));
ensure!(s.contains(81));
Ok(())
}
#[test]
fn test_port_set_18() -> Result<(), Errno> {
let mut s = PortSet::full();
s.remove_range(PortRange::full());
ensure!(s.is_clear());
Ok(())
}
#[test]
fn test_port_set_19() -> Result<(), Errno> {
let mut s = PortSet::empty();
s.remove_range(PortRange::new(80, 90));
ensure!(s.is_clear());
Ok(())
}
#[test]
fn test_port_set_20() -> Result<(), Errno> {
let mut a: PortSet = 80u16.into();
let b: PortSet = 443u16.into();
a.union_with(&b);
ensure!(a.contains(80));
ensure!(a.contains(443));
ensure!(!a.contains(81));
Ok(())
}
#[test]
fn test_port_set_21() -> Result<(), Errno> {
let mut a = PortSet::empty();
a.union_with(&PortSet::full());
ensure!(a.is_full());
Ok(())
}
#[test]
fn test_port_set_22() -> Result<(), Errno> {
let mut a = PortSet::empty();
a.union_with(&PortSet::empty());
ensure!(a.is_clear());
Ok(())
}
#[test]
fn test_port_set_23() -> Result<(), Errno> {
let mut a = PortSet::full();
a.difference_with(&PortSet::full());
ensure!(a.is_clear());
Ok(())
}
#[test]
fn test_port_set_24() -> Result<(), Errno> {
let mut a: PortSet = 80u16.into();
a.difference_with(&PortSet::empty());
ensure!(a.contains(80));
Ok(())
}
#[test]
fn test_port_set_25() -> Result<(), Errno> {
let mut a = PortSet::empty();
a.difference_with(&PortSet::full());
ensure!(a.is_clear());
Ok(())
}
#[test]
fn test_port_set_26() -> Result<(), Errno> {
ensure_eq!(PortSet::empty().count_ones(..), 0);
ensure_eq!(PortSet::full().count_ones(..), PORT_SET_CAPACITY);
ensure_eq!(PortSet::from(80u16).count_ones(..), 1);
Ok(())
}
#[test]
fn test_port_set_27() -> Result<(), Errno> {
let s = PortSet::from(PortRange::new(80, 90));
ensure_eq!(s.count_ones(..), 11);
ensure_eq!(s.count_ones(80..91), 11);
ensure_eq!(s.count_ones(85..91), 6);
ensure_eq!(s.count_ones(0..80), 0);
Ok(())
}
#[test]
fn test_port_set_28() -> Result<(), Errno> {
ensure_eq!(PortSet::full().count_ones(0..100), 100);
ensure_eq!(PortSet::from(80u16).count_ones(0..80), 0);
ensure_eq!(PortSet::from(80u16).count_ones(0..81), 1);
Ok(())
}
#[test]
fn test_port_set_29() -> Result<(), Errno> {
let mut s = PortSet::full();
s.clear();
ensure!(s.is_clear());
Ok(())
}
#[test]
fn test_port_set_30() -> Result<(), Errno> {
let mut s: PortSet = 80u16.into();
s.clear();
ensure!(s.is_clear());
ensure!(!s.contains(80));
Ok(())
}
#[test]
fn test_port_set_31() -> Result<(), Errno> {
let s = PortSet::full();
ensure!(s.is_full());
ensure!(!s.is_clear());
ensure!(s.contains(0));
ensure!(s.contains(65535));
Ok(())
}
#[test]
fn test_port_set_32() -> Result<(), Errno> {
let s = PortSet::empty();
ensure!(!s.is_full());
ensure!(s.is_clear());
ensure!(!s.contains(0));
Ok(())
}
#[test]
fn test_port_set_33() -> Result<(), Errno> {
let s: PortSet = 80u16.into();
ensure!(s.contains(80));
ensure!(!s.contains(81));
ensure!(!s.is_full());
Ok(())
}
#[test]
fn test_port_set_34() -> Result<(), Errno> {
let s: PortSet = 0u16.into();
ensure!(s.contains(0));
ensure!(!s.contains(1));
Ok(())
}
#[test]
fn test_port_set_35() -> Result<(), Errno> {
let s: PortSet = PortRange::new(80, 90).into();
ensure!(s.contains(80));
ensure!(s.contains(85));
ensure!(s.contains(90));
ensure!(!s.contains(91));
Ok(())
}
#[test]
fn test_port_set_36() -> Result<(), Errno> {
ensure!(PortSet::from(PortRange::full()).is_full());
Ok(())
}
#[test]
fn test_port_set_37() -> Result<(), Errno> {
let mut s = PortSet::empty();
s.insert(443);
ensure!(s.contains(443));
ensure!(!s.contains(444));
Ok(())
}
#[test]
fn test_port_set_38() -> Result<(), Errno> {
let mut s = PortSet::empty();
s.insert_range(PortRange::new(100, 200));
ensure!(s.contains(100));
ensure!(s.contains(200));
ensure!(!s.contains(201));
Ok(())
}
#[test]
fn test_port_set_39() -> Result<(), Errno> {
let mut s = PortSet::full();
s.insert_range(PortRange::new(100, 200));
ensure!(s.is_full());
Ok(())
}
#[test]
fn test_port_set_40() -> Result<(), Errno> {
let mut s = PortSet::full();
s.remove_range(PortRange::single(80));
ensure!(!s.is_full());
ensure!(!s.contains(80));
ensure!(s.contains(79));
ensure!(s.contains(81));
Ok(())
}
#[test]
fn test_port_set_41() -> Result<(), Errno> {
let mut s: PortSet = PortRange::new(80, 90).into();
s.remove_range(PortRange::new(85, 90));
ensure!(s.contains(84));
ensure!(!s.contains(85));
Ok(())
}
#[test]
fn test_port_set_42() -> Result<(), Errno> {
let mut a: PortSet = 80u16.into();
let b: PortSet = 443u16.into();
a.union_with(&b);
ensure!(a.contains(80));
ensure!(a.contains(443));
ensure!(!a.contains(81));
Ok(())
}
#[test]
fn test_port_set_43() -> Result<(), Errno> {
let mut a: PortSet = 80u16.into();
a.union_with(&PortSet::full());
ensure!(a.is_full());
Ok(())
}
#[test]
fn test_port_set_44() -> Result<(), Errno> {
let mut a = PortSet::full();
let b: PortSet = 80u16.into();
a.union_with(&b);
ensure!(a.is_full());
Ok(())
}
#[test]
fn test_port_set_45() -> Result<(), Errno> {
let mut a = PortSet::full();
a.difference_with(&PortSet::full());
ensure!(a.is_clear());
Ok(())
}
#[test]
fn test_port_set_46() -> Result<(), Errno> {
let mut a = PortSet::full();
let b: PortSet = 80u16.into();
a.difference_with(&b);
ensure!(!a.contains(80));
ensure!(a.contains(79));
Ok(())
}
#[test]
fn test_port_set_47() -> Result<(), Errno> {
let mut a: PortSet = 80u16.into();
a.difference_with(&PortSet::full());
ensure!(a.is_clear());
Ok(())
}
#[test]
fn test_port_set_48() -> Result<(), Errno> {
let s: PortSet = 80u16.into();
let v: Vec<usize> = s.ones().collect();
ensure_eq!(v, vec![80]);
Ok(())
}
#[test]
fn test_port_set_49() -> Result<(), Errno> {
ensure_eq!(PortSet::full().ones().count(), 65536);
Ok(())
}
#[test]
fn test_port_set_50() -> Result<(), Errno> {
ensure_eq!(PortSet::empty().ones().count(), 0);
Ok(())
}
#[test]
fn test_port_set_51() -> Result<(), Errno> {
ensure_eq!(PortSet::full().count_ones(..), PORT_SET_CAPACITY);
Ok(())
}
#[test]
fn test_port_set_52() -> Result<(), Errno> {
let s: PortSet = PortRange::new(80, 90).into();
ensure_eq!(s.count_ones(..), 11);
Ok(())
}
#[test]
fn test_port_set_53() -> Result<(), Errno> {
let mut s = PortSet::full();
s.clear();
ensure!(s.is_clear());
Ok(())
}
#[test]
fn test_port_set_54() -> Result<(), Errno> {
let mut s: PortSet = 80u16.into();
s.clear();
ensure!(s.is_clear());
Ok(())
}
#[test]
fn test_port_set_55() -> Result<(), Errno> {
let mut set = PortSet::empty();
set.insert(80);
set.insert(81);
ensure!(matches!(set, PortSet::Range(_)));
ensure!(set.contains(80));
ensure!(set.contains(81));
let mut set = PortSet::empty();
set.insert(80);
set.insert(443);
ensure!(matches!(set, PortSet::Set(_)));
let mut set = PortSet::Range(PortRange::new(1, 3));
set.insert(0);
ensure!(matches!(set, PortSet::Range(_)));
ensure_eq!(set.ones().count(), 4);
let mut set = PortSet::Range(PortRange::new(65533, 65534));
set.insert(65535);
ensure!(matches!(set, PortSet::Range(_)));
ensure!(set.contains(65535));
let mut set = PortSet::empty();
set.insert(80);
set.insert(443);
set.insert_range(PortRange::new(81, 442));
ensure!(matches!(set, PortSet::Range(_)));
ensure_eq!(set.ones().count(), 364);
let mut set = PortSet::Range(PortRange::new(0, 32767));
set.insert_range(PortRange::new(32768, 65535));
ensure!(set.is_full());
let mut set = PortSet::One(79);
set.insert_range(PortRange::new(80, 90));
ensure!(matches!(set, PortSet::Range(_)));
ensure!(set.contains(79));
ensure!(set.contains(90));
let mut set = PortSet::Full;
set.remove_range(PortRange::new(0, 0));
ensure!(!set.is_full());
ensure!(!set.contains(0));
ensure!(set.contains(1));
let mut set = PortSet::Full;
set.remove_range(PortRange::new(0, 65534));
ensure!(matches!(set, PortSet::One(65535)));
let mut set = PortSet::Full;
set.remove_range(PortRange::new(1, 65535));
ensure!(matches!(set, PortSet::One(0)));
let mut set = PortSet::Range(PortRange::new(80, 81));
set.remove_range(PortRange::single(80));
ensure!(matches!(set, PortSet::One(81)));
let mut set: PortSet = 80u16.into();
set.insert(443);
set.remove_range(PortRange::new(0, 65535));
ensure!(set.is_clear());
let mut set = PortSet::empty();
set.insert(80);
set.insert(443);
set.remove_range(PortRange::single(443));
ensure!(matches!(set, PortSet::One(80)));
let mut set = PortSet::empty();
set.insert(80);
set.insert(443);
set.insert_range(PortRange::new(81, 442));
set.remove_range(PortRange::single(80));
ensure!(matches!(set, PortSet::Range(_)));
ensure!(!set.contains(80));
ensure!(set.contains(81));
let mut set = PortSet::empty();
set.insert(80);
set.insert(82);
set.union_with(&PortSet::One(81));
ensure!(matches!(set, PortSet::Range(_)));
let mut set = PortSet::Range(PortRange::new(80, 90));
let other = PortSet::Range(PortRange::new(81, 90));
set.difference_with(&other);
ensure!(matches!(set, PortSet::One(80)));
let range_set = PortSet::Range(PortRange::new(80, 90));
let mut bitset = PortSet::empty();
bitset.insert_range(PortRange::new(80, 90));
ensure!(range_set == bitset);
let mut set = PortSet::Range(PortRange::new(1, 5));
set.insert(0);
ensure!(matches!(set, PortSet::Range(_)));
ensure_eq!(set.ones().count(), 6);
let mut set = PortSet::One(65534);
set.insert_range(PortRange::new(65535, 65535));
ensure!(matches!(set, PortSet::Range(_)));
ensure!(set.contains(65534));
ensure!(set.contains(65535));
let mut set = PortSet::Range(PortRange::new(0, 65534));
set.insert(65535);
ensure!(set.is_full());
let mut set = PortSet::empty();
set.insert(10);
set.insert(20);
set.remove_range(PortRange::single(20));
ensure!(matches!(set, PortSet::One(10)));
let mut set = PortSet::empty();
set.insert(0);
set.insert(65535);
set.insert_range(PortRange::new(1, 65534));
ensure!(set.is_full());
let mut set = PortSet::empty();
set.insert(100);
set.insert(200);
set.remove_range(PortRange::new(0, 65535));
ensure!(matches!(set, PortSet::None));
let mut set = PortSet::Range(PortRange::new(80, 90));
set.remove_range(PortRange::new(100, 200));
ensure!(matches!(set, PortSet::Range(_)));
ensure_eq!(set.ones().count(), 11);
let mut set = PortSet::One(80);
set.remove_range(PortRange::new(100, 200));
ensure!(matches!(set, PortSet::One(80)));
let mut set = PortSet::Range(PortRange::new(80, 100));
set.insert_range(PortRange::new(90, 120));
ensure!(matches!(set, PortSet::Range(_)));
ensure_eq!(set.ones().count(), 41);
let mut set = PortSet::Range(PortRange::new(80, 90));
set.insert_range(PortRange::new(200, 210));
ensure!(matches!(set, PortSet::Set(_)));
let mut set = PortSet::None;
set.union_with(&PortSet::One(42));
ensure!(matches!(set, PortSet::One(42)));
let mut set = PortSet::One(42);
set.difference_with(&PortSet::None);
ensure!(matches!(set, PortSet::One(42)));
let mut set = PortSet::None;
set.difference_with(&PortSet::One(42));
ensure!(matches!(set, PortSet::None));
let mut set = PortSet::empty();
set.insert(80);
set.insert(82);
let mut other = PortSet::empty();
other.insert(81);
set.union_with(&other);
ensure!(matches!(set, PortSet::Range(_)));
ensure_eq!(set.ones().count(), 3);
let mut set = PortSet::empty();
set.insert(80);
set.insert(81);
set.insert(82);
let mut other = PortSet::empty();
other.insert(81);
other.insert(82);
set.difference_with(&other);
ensure!(matches!(set, PortSet::One(80)));
let mut set = PortSet::Full;
set.insert(80);
ensure!(set.is_full());
let mut set = PortSet::One(80);
set.insert(80);
ensure!(matches!(set, PortSet::One(80)));
let mut set = PortSet::Range(PortRange::new(80, 90));
set.insert(85);
ensure!(matches!(set, PortSet::Range(_)));
ensure_eq!(set.ones().count(), 11);
let mut set = PortSet::Range(PortRange::new(80, 90));
set.insert(200);
ensure!(matches!(set, PortSet::Set(_)));
ensure!(set.contains(80));
ensure!(set.contains(90));
ensure!(set.contains(200));
ensure!(!set.contains(91));
let mut set = PortSet::Range(PortRange::new(1, 65535));
set.insert(0);
ensure!(set.is_full());
let mut set = PortSet::Range(PortRange::new(0, 65534));
set.insert(65535);
ensure!(set.is_full());
let mut set = PortSet::One(80);
set.insert_range(PortRange::full());
ensure!(set.is_full());
let mut set = PortSet::Range(PortRange::new(80, 90));
set.insert_range(PortRange::full());
ensure!(set.is_full());
let mut set = PortSet::empty();
set.insert(80);
set.insert(443);
set.insert_range(PortRange::full());
ensure!(set.is_full());
let mut set = PortSet::Full;
set.insert_range(PortRange::new(80, 90));
ensure!(set.is_full());
let mut set = PortSet::None;
set.insert_range(PortRange::single(42));
ensure!(matches!(set, PortSet::One(42)));
let mut set = PortSet::None;
set.insert_range(PortRange::new(80, 90));
ensure!(matches!(set, PortSet::Range(_)));
let mut set = PortSet::One(85);
set.insert_range(PortRange::new(80, 90));
ensure!(matches!(set, PortSet::Range(_)));
ensure_eq!(set.ones().count(), 11);
let mut set = PortSet::One(80);
set.insert_range(PortRange::single(80));
ensure!(matches!(set, PortSet::One(80)));
let mut set = PortSet::One(80);
set.insert_range(PortRange::new(200, 210));
ensure!(matches!(set, PortSet::Set(_)));
ensure!(set.contains(80));
ensure!(set.contains(200));
ensure!(set.contains(210));
let mut set = PortSet::Range(PortRange::new(80, 200));
set.insert_range(PortRange::new(90, 100));
ensure!(matches!(set, PortSet::Range(_)));
ensure_eq!(set.ones().count(), 121);
let mut set = PortSet::None;
set.remove_range(PortRange::new(80, 90));
ensure!(matches!(set, PortSet::None));
let mut set = PortSet::Full;
set.remove_range(PortRange::full());
ensure!(matches!(set, PortSet::None));
let mut set = PortSet::Full;
set.remove_range(PortRange::new(100, 200));
ensure!(matches!(set, PortSet::Set(_)));
ensure!(!set.contains(100));
ensure!(!set.contains(200));
ensure!(set.contains(99));
ensure!(set.contains(201));
let mut set = PortSet::Range(PortRange::new(80, 200));
set.remove_range(PortRange::new(100, 150));
ensure!(matches!(set, PortSet::Set(_)));
ensure!(set.contains(80));
ensure!(set.contains(99));
ensure!(!set.contains(100));
ensure!(!set.contains(150));
ensure!(set.contains(151));
ensure!(set.contains(200));
let mut set = PortSet::One(80);
set.remove_range(PortRange::new(81, 90));
ensure!(matches!(set, PortSet::One(80)));
let mut set = PortSet::Range(PortRange::new(80, 90));
set.remove_range(PortRange::new(80, 90));
ensure!(matches!(set, PortSet::None));
let mut set = PortSet::Range(PortRange::new(80, 81));
set.remove_range(PortRange::single(81));
ensure!(matches!(set, PortSet::One(80)));
let mut set = PortSet::Full;
set.union_with(&PortSet::One(80));
ensure!(set.is_full());
let mut set = PortSet::One(80);
set.union_with(&PortSet::Full);
ensure!(set.is_full());
let mut set = PortSet::Range(PortRange::new(80, 90));
set.union_with(&PortSet::One(85));
ensure!(matches!(set, PortSet::Range(_)));
ensure_eq!(set.ones().count(), 11);
let mut set = PortSet::One(85);
set.union_with(&PortSet::Range(PortRange::new(80, 90)));
ensure!(matches!(set, PortSet::Range(_)));
ensure_eq!(set.ones().count(), 11);
let mut set = PortSet::Full;
set.difference_with(&PortSet::One(80));
ensure!(!set.contains(80));
ensure!(set.contains(79));
ensure!(set.contains(81));
let mut set = PortSet::One(80);
set.difference_with(&PortSet::One(80));
ensure!(matches!(set, PortSet::None));
let mut set = PortSet::One(80);
set.difference_with(&PortSet::One(443));
ensure!(matches!(set, PortSet::One(80)));
let mut set = PortSet::Range(PortRange::new(80, 90));
set.difference_with(&PortSet::Range(PortRange::new(80, 90)));
ensure!(matches!(set, PortSet::None));
let mut set = PortSet::empty();
set.insert(80);
set.insert(443);
set.insert(8080);
ensure!(matches!(set, PortSet::Set(_)));
let set = PortSet::One(80);
ensure_eq!(set.count_ones(0..81), 1);
ensure_eq!(set.count_ones(0..80), 0);
ensure_eq!(set.count_ones(81..100), 0);
let set = PortSet::Range(PortRange::new(80, 90));
ensure_eq!(set.count_ones(80..91), 11);
ensure_eq!(set.count_ones(85..91), 6);
ensure_eq!(set.count_ones(0..80), 0);
ensure_eq!(set.count_ones(91..100), 0);
ensure_eq!(PortSet::None.count_ones(..), 0);
ensure_eq!(PortSet::Full.count_ones(..), PORT_SET_CAPACITY);
ensure_eq!(PortSet::Full.count_ones(0..100), 100);
let mut set = PortSet::empty();
set.insert(443);
set.insert(80);
set.insert(8080);
let ports: Vec<usize> = set.ones().collect();
ensure_eq!(ports, vec![80, 443, 8080]);
Ok(())
}
#[test]
fn test_port_set_56() -> Result<(), Errno> {
ensure_eq!(PortSet::None, PortSet::None);
ensure_eq!(PortSet::Full, PortSet::Full);
ensure_eq!(PortSet::One(80), PortSet::One(80));
ensure!(PortSet::One(80) != PortSet::One(443));
let left = PortSet::Range(PortRange::new(80, 90));
let right = PortSet::Range(PortRange::new(80, 90));
ensure_eq!(left, right);
ensure!(PortSet::Range(PortRange::new(80, 90)) != PortSet::Range(PortRange::new(80, 91)));
let mut left = PortSet::empty();
left.insert(80);
left.insert(443);
let mut right = PortSet::empty();
right.insert(443);
right.insert(80);
ensure_eq!(left, right);
let mut left = PortSet::empty();
left.insert(80);
let mut right = PortSet::empty();
right.insert(443);
ensure!(left != right);
ensure!(PortSet::None != PortSet::Full);
ensure!(PortSet::None != PortSet::One(80));
ensure!(PortSet::None != PortSet::Range(PortRange::new(80, 90)));
let empty_set = PortSet::empty();
ensure_eq!(PortSet::None, empty_set);
let mut nonempty = PortSet::empty();
nonempty.insert(80);
ensure!(PortSet::None != nonempty);
ensure!(PortSet::Full != PortSet::None);
ensure!(PortSet::Full != PortSet::One(80));
ensure!(PortSet::Full != PortSet::Range(PortRange::new(80, 90)));
ensure_eq!(PortSet::Full, PortSet::Range(PortRange::full()));
ensure!(PortSet::One(80) != PortSet::None);
ensure!(PortSet::One(80) != PortSet::Full);
ensure_eq!(PortSet::One(80), PortSet::Range(PortRange::single(80)));
ensure!(PortSet::One(80) != PortSet::Range(PortRange::new(80, 81)));
let mut set = PortSet::empty();
set.insert(80);
let mut forced_set = PortSet::Set(FixedBitSet::with_capacity(81));
if let PortSet::Set(ref mut bits) = forced_set {
bits.insert(80);
}
ensure_eq!(PortSet::One(80), forced_set);
let mut forced_set = PortSet::Set(FixedBitSet::with_capacity(444));
if let PortSet::Set(ref mut bits) = forced_set {
bits.insert(443);
}
ensure!(PortSet::One(80) != forced_set);
let mut forced_set = PortSet::Set(FixedBitSet::with_capacity(444));
if let PortSet::Set(ref mut bits) = forced_set {
bits.insert(80);
bits.insert(443);
}
ensure!(PortSet::One(80) != forced_set);
let mut forced_set = PortSet::Set(FixedBitSet::with_capacity(91));
if let PortSet::Set(ref mut bits) = forced_set {
bits.insert_range(80..91);
}
ensure_eq!(PortSet::Range(PortRange::new(80, 90)), forced_set);
let mut forced_set = PortSet::Set(FixedBitSet::with_capacity(444));
if let PortSet::Set(ref mut bits) = forced_set {
bits.insert_range(80..91);
bits.insert(443);
}
ensure!(PortSet::Range(PortRange::new(80, 90)) != forced_set);
let mut forced_set = PortSet::Set(FixedBitSet::with_capacity(91));
if let PortSet::Set(ref mut bits) = forced_set {
bits.insert_range(80..90);
}
ensure!(PortSet::Range(PortRange::new(80, 90)) != forced_set);
let mut forced_set = PortSet::Set(FixedBitSet::with_capacity(91));
if let PortSet::Set(ref mut bits) = forced_set {
bits.insert_range(80..91);
}
ensure_eq!(forced_set, PortSet::Range(PortRange::new(80, 90)));
let mut forced_set = PortSet::Set(FixedBitSet::with_capacity(81));
if let PortSet::Set(ref mut bits) = forced_set {
bits.insert(80);
}
ensure_eq!(forced_set, PortSet::One(80));
ensure_eq!(PortSet::One(0), PortSet::Range(PortRange::single(0)));
ensure_eq!(
PortSet::One(65535),
PortSet::Range(PortRange::single(65535))
);
ensure_eq!(PortSet::Range(PortRange::new(0, 65535)), PortSet::Full);
ensure_eq!(PortSet::Full, PortSet::Range(PortRange::new(0, 65535)));
ensure!(PortSet::None != PortSet::One(0));
ensure!(PortSet::One(0) != PortSet::None);
ensure!(PortSet::None != PortSet::Range(PortRange::new(0, 0)));
ensure!(PortSet::Range(PortRange::new(0, 0)) != PortSet::None);
ensure!(PortSet::Full != PortSet::One(0));
ensure!(PortSet::One(0) != PortSet::Full);
let mut partial = PortSet::Set(FixedBitSet::with_capacity(PORT_SET_CAPACITY));
if let PortSet::Set(ref mut bits) = partial {
bits.insert(80);
}
ensure!(PortSet::Full != partial);
ensure!(partial != PortSet::Full);
ensure_eq!(PortSet::None, PortSet::Set(FixedBitSet::new()));
ensure_eq!(PortSet::Set(FixedBitSet::new()), PortSet::None);
ensure_eq!(PortSet::One(0), PortSet::Range(PortRange::single(0)));
ensure_eq!(
PortSet::One(65535),
PortSet::Range(PortRange::single(65535))
);
ensure_eq!(PortSet::Range(PortRange::single(0)), PortSet::One(0));
ensure_eq!(
PortSet::Range(PortRange::single(65535)),
PortSet::One(65535)
);
ensure!(PortSet::One(80) != PortSet::Range(PortRange::single(81)));
let mut full_set = PortSet::Set(FixedBitSet::with_capacity(PORT_SET_CAPACITY));
if let PortSet::Set(ref mut bits) = full_set {
bits.insert_range(..);
}
ensure_eq!(full_set, PortSet::Full);
ensure_eq!(PortSet::Full, full_set);
let mut forced = PortSet::Set(FixedBitSet::with_capacity(91));
if let PortSet::Set(ref mut bits) = forced {
bits.insert_range(80..91);
}
ensure_eq!(forced.clone(), PortSet::Range(PortRange::new(80, 90)));
ensure_eq!(PortSet::Range(PortRange::new(80, 90)), forced);
let mut gapped = PortSet::Set(FixedBitSet::with_capacity(91));
if let PortSet::Set(ref mut bits) = gapped {
bits.insert_range(80..85);
bits.insert_range(87..91);
}
ensure!(PortSet::Range(PortRange::new(80, 90)) != gapped);
let mut forced = PortSet::Set(FixedBitSet::with_capacity(1));
if let PortSet::Set(ref mut bits) = forced {
bits.insert(0);
}
ensure_eq!(PortSet::One(0), forced);
let mut forced = PortSet::Set(FixedBitSet::with_capacity(PORT_SET_CAPACITY));
if let PortSet::Set(ref mut bits) = forced {
bits.insert(65535);
}
ensure_eq!(PortSet::One(65535), forced);
Ok(())
}
#[test]
fn test_parse_port_range() -> Result<(), Errno> {
ensure_eq!(parse_port_range("80")?, PortRange::single(80));
ensure_eq!(parse_port_range("0")?, PortRange::single(0));
ensure_eq!(parse_port_range("65535")?, PortRange::single(65535));
ensure_eq!(parse_port_range("1024-65535")?, PortRange::new(1024, 65535));
ensure_eq!(parse_port_range("80-443")?, PortRange::new(80, 443));
ensure_eq!(parse_port_range("100-50")?, PortRange::new(50, 100));
ensure_eq!(parse_port_range("8080-8080")?, PortRange::single(8080));
ensure!(parse_port_range("").is_err());
ensure!(parse_port_range("abc").is_err());
ensure!(parse_port_range("-1").is_err());
ensure!(parse_port_range("65536").is_err());
ensure!(parse_port_range("80-abc").is_err());
ensure!(parse_port_range("abc-80").is_err());
Ok(())
}
#[test]
fn test_parse_port_set_1() -> Result<(), Errno> {
ensure_eq!(parse_port_set("80")?, portset_from_ports(&[80]));
Ok(())
}
#[test]
fn test_parse_port_set_2() -> Result<(), Errno> {
ensure_eq!(parse_port_set("80-443")?, portset_from_ranges(&[80..=443]));
Ok(())
}
#[test]
fn test_parse_port_set_3() -> Result<(), Errno> {
ensure_eq!(parse_port_set("80,443")?, portset_from_ports(&[80, 443]));
Ok(())
}
#[test]
fn test_parse_port_set_4() -> Result<(), Errno> {
ensure!(parse_port_set("*").is_err());
Ok(())
}
#[test]
fn test_parse_port_set_5() -> Result<(), Errno> {
ensure!(parse_port_set("").is_err());
ensure!(parse_port_set("abc").is_err());
ensure!(parse_port_set("80,abc").is_err());
ensure!(parse_port_set("80,,443").is_err());
ensure!(parse_port_set(",80").is_err());
ensure!(parse_port_set("80,").is_err());
ensure!(parse_port_set("65536").is_err());
ensure!(parse_port_set("-1").is_err());
Ok(())
}
#[test]
fn test_parse_port_set_6() -> Result<(), Errno> {
let mut expected = portset_from_ports(&[80, 443]);
expected.union_with(&portset_from_ranges(&[8000..=9000]));
ensure_eq!(parse_port_set("80,443,8000-9000")?, expected);
Ok(())
}
#[test]
fn test_parse_port_set_7() -> Result<(), Errno> {
ensure_eq!(
parse_port_set("0-65535")?,
portset_from_ranges(&[0..=65535])
);
Ok(())
}
#[test]
fn test_parse_port_set_8() -> Result<(), Errno> {
ensure_eq!(parse_port_set("80")?, portset_from_ports(&[80]));
ensure_eq!(parse_port_set("0")?, portset_from_ports(&[0]));
ensure_eq!(parse_port_set("65535")?, portset_from_ports(&[65535]));
ensure_eq!(
parse_port_set("1024-65535")?,
portset_from_ranges(&[1024..=65535])
);
ensure_eq!(parse_port_set("80,443")?, portset_from_ports(&[80, 443]));
ensure_eq!(
parse_port_set("22,80,443,8080")?,
portset_from_ports(&[22, 80, 443, 8080])
);
let mut expected = portset_from_ports(&[80, 443]);
expected.union_with(&portset_from_ranges(&[8000..=9000]));
ensure_eq!(parse_port_set("80,443,8000-9000")?, expected);
ensure_eq!(
parse_port_set("80-100,90-110")?,
portset_from_ranges(&[80..=110])
);
ensure_eq!(parse_port_set("100-50")?, portset_from_ranges(&[50..=100]));
ensure!(parse_port_set("").is_err());
ensure!(parse_port_set("abc").is_err());
ensure!(parse_port_set("80,abc").is_err());
ensure!(parse_port_set("80,,443").is_err());
ensure!(parse_port_set(",80").is_err());
ensure!(parse_port_set("80,").is_err());
ensure!(parse_port_set("65536").is_err());
Ok(())
}
}