use crate::Interceptor;
use crate::TaggedPacket;
use crate::stream_info::StreamInfo;
use sansio::Protocol;
use shared::error::Error;
use std::collections::VecDeque;
use std::time::Instant;
#[derive(Default)]
pub(crate) struct Chain {
interceptors: Vec<Box<dyn Interceptor>>,
read_outs: VecDeque<TaggedPacket>,
write_outs: VecDeque<TaggedPacket>,
}
impl Chain {
pub(crate) fn new(interceptors: Vec<Box<dyn Interceptor>>) -> Self {
Self {
interceptors,
..Self::default()
}
}
pub(crate) fn len(&self) -> usize {
self.interceptors.len()
}
pub(crate) fn is_empty(&self) -> bool {
self.interceptors.is_empty()
}
fn walk<'a, T>(
interceptors: impl Iterator<Item = &'a mut Box<dyn Interceptor>>,
mut belt: VecDeque<T>,
handle: fn(&mut dyn Interceptor, T) -> Result<(), Error>,
poll: fn(&mut dyn Interceptor) -> Option<T>,
) -> VecDeque<T> {
for interceptor in interceptors {
while let Some(next) = belt.pop_front() {
if let Err(err) = handle(interceptor.as_mut(), next) {
log::warn!("interceptor handle failed: {err}");
}
}
while let Some(next) = poll(interceptor.as_mut()) {
belt.push_back(next);
}
}
belt
}
fn drain_read(&mut self) {
let belt = Self::walk(
self.interceptors.iter_mut(),
VecDeque::new(),
|s, p| s.handle_read(p),
|s| s.poll_read(),
);
self.read_outs.extend(belt);
}
fn drain_write(&mut self) {
let belt = Self::walk(
self.interceptors.iter_mut().rev(),
VecDeque::new(),
|s, p| s.handle_write(p),
|s| s.poll_write(),
);
self.write_outs.extend(belt);
}
}
impl Protocol<TaggedPacket, TaggedPacket, ()> for Chain {
type Rout = TaggedPacket;
type Wout = TaggedPacket;
type Eout = ();
type Error = Error;
type Time = Instant;
fn handle_read(&mut self, msg: TaggedPacket) -> Result<(), Self::Error> {
let belt = Self::walk(
self.interceptors.iter_mut(),
VecDeque::from([msg]),
|s, p| s.handle_read(p),
|s| s.poll_read(),
);
self.read_outs.extend(belt);
Ok(())
}
fn poll_read(&mut self) -> Option<Self::Rout> {
if self.read_outs.is_empty() {
self.drain_read();
}
self.read_outs.pop_front()
}
fn handle_write(&mut self, msg: TaggedPacket) -> Result<(), Self::Error> {
let belt = Self::walk(
self.interceptors.iter_mut().rev(),
VecDeque::from([msg]),
|s, p| s.handle_write(p),
|s| s.poll_write(),
);
self.write_outs.extend(belt);
Ok(())
}
fn poll_write(&mut self) -> Option<Self::Wout> {
if self.write_outs.is_empty() {
self.drain_write();
}
self.write_outs.pop_front()
}
fn handle_timeout(&mut self, now: Self::Time) -> Result<(), Self::Error> {
for interceptor in self.interceptors.iter_mut() {
interceptor.handle_timeout(now)?;
}
Ok(())
}
fn poll_timeout(&mut self) -> Option<Self::Time> {
self.interceptors
.iter_mut()
.filter_map(|interceptor| interceptor.poll_timeout())
.min()
}
fn close(&mut self) -> Result<(), Self::Error> {
for interceptor in self.interceptors.iter_mut() {
interceptor.close()?;
}
Ok(())
}
}
impl Interceptor for Chain {
fn bind_local_stream(&mut self, info: &StreamInfo) {
for interceptor in self.interceptors.iter_mut() {
interceptor.bind_local_stream(info);
}
}
fn unbind_local_stream(&mut self, info: &StreamInfo) {
for interceptor in self.interceptors.iter_mut() {
interceptor.unbind_local_stream(info);
}
}
fn bind_remote_stream(&mut self, info: &StreamInfo) {
for interceptor in self.interceptors.iter_mut() {
interceptor.bind_remote_stream(info);
}
}
fn unbind_remote_stream(&mut self, info: &StreamInfo) {
for interceptor in self.interceptors.iter_mut() {
interceptor.unbind_remote_stream(info);
}
}
}