use crate::ifaddr::InterfaceAddressId;
use crate::interface::InterfaceId;
use crate::neighbor::NeighborId;
use crate::route::RouteId;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum ChangeKind {
Added,
Removed,
Changed,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum EventDomain {
Route,
Interface,
Neighbor,
Address,
All,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct EventFilter {
routes: bool,
interfaces: bool,
neighbors: bool,
addresses: bool,
}
impl EventFilter {
pub const ALL: Self = Self {
routes: true,
interfaces: true,
neighbors: true,
addresses: true,
};
pub const fn none() -> Self {
Self {
routes: false,
interfaces: false,
neighbors: false,
addresses: false,
}
}
pub const fn routes(mut self) -> Self {
self.routes = true;
self
}
pub const fn interfaces(mut self) -> Self {
self.interfaces = true;
self
}
pub const fn neighbors(mut self) -> Self {
self.neighbors = true;
self
}
pub const fn addresses(mut self) -> Self {
self.addresses = true;
self
}
pub const fn matches(self, event: Event) -> bool {
match event {
Event::Route { .. } => self.routes,
Event::Interface { .. } => self.interfaces,
Event::Neighbor { .. } => self.neighbors,
Event::Address { .. } => self.addresses,
Event::ResyncRequired { domain } => match domain {
EventDomain::Route => self.routes,
EventDomain::Interface => self.interfaces,
EventDomain::Neighbor => self.neighbors,
EventDomain::Address => self.addresses,
EventDomain::All => {
self.routes || self.interfaces || self.neighbors || self.addresses
}
},
}
}
}
impl Default for EventFilter {
fn default() -> Self {
Self::ALL
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Event {
Route {
id: RouteId,
kind: ChangeKind,
},
Interface {
id: InterfaceId,
kind: ChangeKind,
},
Neighbor {
id: NeighborId,
kind: ChangeKind,
},
Address {
id: InterfaceAddressId,
kind: ChangeKind,
},
ResyncRequired {
domain: EventDomain,
},
}
impl Event {
pub const fn resync_all() -> Self {
Self::ResyncRequired {
domain: EventDomain::All,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn events_carry_id_and_kind() {
let event = Event::Route {
id: RouteId::new(1),
kind: ChangeKind::Added,
};
assert_eq!(
event,
Event::Route {
id: RouteId::new(1),
kind: ChangeKind::Added,
}
);
assert_ne!(
event,
Event::Route {
id: RouteId::new(1),
kind: ChangeKind::Removed,
}
);
}
}