use crate::messages::TaggedMessageEvent;
use crate::types::FourTuple;
use std::time::Instant;
pub(crate) mod nack;
pub(crate) mod report;
pub(crate) mod twcc;
pub enum InterceptorEvent {
Inbound(TaggedMessageEvent),
Outbound(TaggedMessageEvent),
Error(Box<dyn std::error::Error>),
}
pub trait Interceptor {
fn chain(self: Box<Self>, next: Box<dyn Interceptor>) -> Box<dyn Interceptor>;
fn next(&mut self) -> Option<&mut Box<dyn Interceptor>>;
fn read(&mut self, msg: &mut TaggedMessageEvent) -> Vec<InterceptorEvent> {
if let Some(next) = self.next() {
next.read(msg)
} else {
vec![]
}
}
fn write(&mut self, msg: &mut TaggedMessageEvent) -> Vec<InterceptorEvent> {
if let Some(next) = self.next() {
next.write(msg)
} else {
vec![]
}
}
fn handle_timeout(&mut self, now: Instant, four_tuples: &[FourTuple]) -> Vec<InterceptorEvent> {
if let Some(next) = self.next() {
next.handle_timeout(now, four_tuples)
} else {
vec![]
}
}
fn poll_timeout(&mut self, eto: &mut Instant) {
if let Some(next) = self.next() {
next.poll_timeout(eto);
}
}
}
pub trait InterceptorBuilder {
fn build(&self, id: &str) -> Box<dyn Interceptor>;
}
#[derive(Default)]
pub struct Registry {
builders: Vec<Box<dyn InterceptorBuilder + Send + Sync>>,
}
impl Registry {
pub fn new() -> Self {
Registry::default()
}
pub fn add(&mut self, builder: Box<dyn InterceptorBuilder + Send + Sync>) {
self.builders.push(builder);
}
pub fn build(&self, id: &str) -> Box<dyn Interceptor> {
let mut next = Box::new(NoOp) as Box<dyn Interceptor>;
for interceptor in self.builders.iter().rev().map(|b| b.build(id)) {
next = interceptor.chain(next);
}
next
}
}
struct NoOp;
impl Interceptor for NoOp {
fn chain(self: Box<Self>, _next: Box<dyn Interceptor>) -> Box<dyn Interceptor> {
self
}
fn next(&mut self) -> Option<&mut Box<dyn Interceptor>> {
None
}
}