use std::hash::Hash;
use serde::{Deserialize, Serialize};
mod queue;
pub use queue::{BasicEventQueue, ConcurrentEventQueue, EventQueue, FmtPriority, PerRouterQueue};
#[cfg(feature = "rand_queue")]
mod rand_queue;
#[cfg(feature = "rand_queue")]
pub use rand_queue::{GeoTimingModel, ModelParams, SimpleTimingModel};
use crate::{
bgp::BgpEvent,
ospf::{local::OspfEvent, OspfArea},
types::{IntoIpv4Prefix, Ipv4Prefix, Prefix, RouterId, StepUpdate},
};
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(bound(
serialize = "P: Serialize, T: serde::Serialize",
deserialize = "P: for<'a> serde::Deserialize<'a>, T: for<'a> serde::Deserialize<'a>"
))]
pub enum Event<P: Prefix, T> {
Bgp {
p: T,
src: RouterId,
dst: RouterId,
e: BgpEvent<P>,
},
Ospf {
p: T,
src: RouterId,
dst: RouterId,
area: OspfArea,
e: OspfEvent,
},
}
impl<P: Prefix, T> Event<P, T> {
pub fn bgp(p: T, src: RouterId, dst: RouterId, e: BgpEvent<P>) -> Self {
Self::Bgp { p, src, dst, e }
}
pub fn ospf(p: T, src: RouterId, dst: RouterId, area: OspfArea, e: OspfEvent) -> Self {
Self::Ospf {
p,
src,
dst,
area,
e,
}
}
pub fn prefix(&self) -> Option<P> {
match self {
Event::Bgp {
e: BgpEvent::Update(route),
..
} => Some(route.prefix),
Event::Bgp {
e: BgpEvent::Withdraw(prefix),
..
} => Some(*prefix),
Event::Ospf { .. } => None,
}
}
pub fn priority(&self) -> &T {
match self {
Event::Bgp { p, .. } | Event::Ospf { p, .. } => p,
}
}
pub fn priority_mut(&mut self) -> &mut T {
match self {
Event::Bgp { p, .. } | Event::Ospf { p, .. } => p,
}
}
pub fn is_bgp_event(&self) -> bool {
matches!(self, Event::Bgp { .. })
}
pub fn source(&self) -> RouterId {
match self {
Event::Bgp { src, .. } | Event::Ospf { src, .. } => *src,
}
}
pub fn router(&self) -> RouterId {
match self {
Event::Bgp { dst, .. } | Event::Ospf { dst, .. } => *dst,
}
}
}
impl<P: Prefix, T> IntoIpv4Prefix for Event<P, T> {
type T = Event<Ipv4Prefix, ()>;
fn into_ipv4_prefix(self) -> Self::T {
match self {
Event::Bgp { src, dst, e, .. } => Event::Bgp {
p: (),
src,
dst,
e: match e {
BgpEvent::Withdraw(p) => BgpEvent::Withdraw(p.into_ipv4_prefix()),
BgpEvent::Update(bgp_route) => BgpEvent::Update(bgp_route.into_ipv4_prefix()),
},
},
Event::Ospf {
src, dst, area, e, ..
} => Event::Ospf {
p: (),
src,
dst,
area,
e,
},
}
}
}
pub(crate) type EventOutcome<P, T> = (StepUpdate<P>, Vec<Event<P, T>>);