use core::fmt;
use crate::table::{Convergence, Timing};
use crate::{Duration, Mac, PortId};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Limits {
pub unicast: u16,
pub broadcast: u16,
}
impl Limits {
pub const MIN: u16 = 64;
#[must_use]
pub const fn both(octets: u16) -> Self {
Self {
unicast: octets,
broadcast: octets,
}
}
#[must_use]
pub const fn get(self, broadcast: bool) -> usize {
if broadcast {
self.broadcast as usize
} else {
self.unicast as usize
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct PortConfig {
pub network: u16,
pub mac: Mac,
pub max_npdu: Limits,
}
impl PortConfig {
pub(super) const ZERO: Self = Self {
network: 0,
mac: Mac::EMPTY,
max_npdu: Limits::both(0),
};
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub struct Options {
pub convergence: Convergence,
pub route_cap: u16,
pub learned_age: Duration,
pub sweep: Duration,
pub timing: Timing,
pub discovery_cooldown: Duration,
pub discovery_age: Duration,
}
impl Options {
pub const HOSTED: Self = Self {
convergence: Convergence::Standard,
route_cap: 256,
learned_age: Duration::from_secs(300),
sweep: Duration::from_secs(60),
timing: Timing::DEFAULT,
discovery_cooldown: Duration::from_secs(5),
discovery_age: Duration::from_secs(30),
};
}
impl Default for Options {
fn default() -> Self {
Self::HOSTED
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum ConfigError {
NoPorts,
TooManyPorts {
count: usize,
capacity: usize,
},
DuplicateNetwork(u16),
Limit(PortId),
RouteCap {
cap: u16,
capacity: usize,
},
TableTooSmall,
ZeroSweep,
}
impl fmt::Display for ConfigError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NoPorts => f.write_str("a router needs at least one port"),
Self::TooManyPorts { count, capacity } => {
write!(f, "{count} ports offered, room for {capacity}")
}
Self::DuplicateNetwork(network) => {
write!(f, "duplicate network number {network} in router ports")
}
Self::Limit(port) => write!(
f,
"port {} has an NPDU limit under 64 octets or over the scratch",
port.0
),
Self::RouteCap { cap, capacity } => {
write!(f, "a route cap of {cap} is over the table's {capacity}")
}
Self::TableTooSmall => f.write_str("the table can't hold every port's network"),
Self::ZeroSweep => f.write_str("the sweep period is zero"),
}
}
}
impl core::error::Error for ConfigError {}