use std::io;
use std::pin::Pin;
use std::task::{Context, Poll};
use futures::channel::mpsc;
use futures::{Sink, Stream};
use smoltcp::phy::{DeviceCapabilities, Medium};
use tokio_smoltcp::device::AsyncDevice;
pub(crate) struct NymAsyncDevice {
rx: mpsc::UnboundedReceiver<Vec<u8>>,
tx: mpsc::UnboundedSender<Vec<u8>>,
capabilities: DeviceCapabilities,
}
impl NymAsyncDevice {
pub(crate) fn new(
rx: mpsc::UnboundedReceiver<Vec<u8>>,
tx: mpsc::UnboundedSender<Vec<u8>>,
) -> Self {
let mut capabilities = DeviceCapabilities::default();
capabilities.medium = Medium::Ip;
capabilities.max_transmission_unit = 1500;
capabilities.max_burst_size = Some(1);
Self {
rx,
tx,
capabilities,
}
}
}
impl Stream for NymAsyncDevice {
type Item = io::Result<Vec<u8>>;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
Pin::new(&mut self.rx).poll_next(cx).map(|opt| opt.map(Ok))
}
}
impl Sink<Vec<u8>> for NymAsyncDevice {
type Error = io::Error;
fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Pin::new(&mut self.tx)
.poll_ready(cx)
.map_err(|_| io::Error::new(io::ErrorKind::BrokenPipe, "bridge channel closed"))
}
fn start_send(mut self: Pin<&mut Self>, item: Vec<u8>) -> Result<(), Self::Error> {
Pin::new(&mut self.tx)
.start_send(item)
.map_err(|_| io::Error::new(io::ErrorKind::BrokenPipe, "bridge channel closed"))
}
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Pin::new(&mut self.tx)
.poll_flush(cx)
.map_err(|_| io::Error::new(io::ErrorKind::BrokenPipe, "bridge channel closed"))
}
fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Pin::new(&mut self.tx)
.poll_close(cx)
.map_err(|_| io::Error::new(io::ErrorKind::BrokenPipe, "bridge channel closed"))
}
}
impl AsyncDevice for NymAsyncDevice {
fn capabilities(&self) -> &DeviceCapabilities {
&self.capabilities
}
}