use super::Transport;
use super::capture::CaptureFile;
use crate::error::ConnectionError;
use crate::error::Error;
use bytes::Bytes;
use futures_util::lock::Mutex;
use std::path::Path;
use std::pin::Pin;
pub struct ReplayTransport {
packets: Mutex<std::collections::VecDeque<Vec<u8>>>,
}
impl ReplayTransport {
pub fn from_capture(capture: CaptureFile) -> Self {
let packets: std::collections::VecDeque<Vec<u8>> = capture
.packets
.iter()
.filter_map(|p| p.decode_payload().ok())
.collect();
Self {
packets: Mutex::new(packets),
}
}
pub fn from_file(path: &Path) -> Result<Self, Error> {
let capture = CaptureFile::load(path).map_err(Error::Io)?;
Ok(Self::from_capture(capture))
}
}
impl Transport for ReplayTransport {
fn send(
&self,
_payload: &[u8],
) -> Pin<Box<dyn std::future::Future<Output = Result<(), Error>> + Send + '_>> {
Box::pin(async { Ok(()) })
}
fn recv(&self) -> Pin<Box<dyn std::future::Future<Output = Result<Bytes, Error>> + Send + '_>> {
Box::pin(async {
self.packets
.lock()
.await
.pop_front()
.map(Bytes::from)
.ok_or_else(|| ConnectionError::Disconnected.into())
})
}
}