90 lines
2.2 KiB
Rust
90 lines
2.2 KiB
Rust
use tokio::{
|
|
io::{AsyncReadExt, AsyncWriteExt},
|
|
net::{
|
|
TcpListener, TcpStream,
|
|
tcp::{OwnedReadHalf, OwnedWriteHalf},
|
|
},
|
|
};
|
|
|
|
#[derive(Default)]
|
|
pub struct State;
|
|
|
|
pub struct Bind(TcpListener);
|
|
|
|
pub struct Wire(String);
|
|
|
|
pub enum Rx {
|
|
Wait(Rx1),
|
|
Bind(Rx1),
|
|
Wire(Rx1),
|
|
}
|
|
pub enum Tx {
|
|
Wait(Tx1),
|
|
Bind(Tx1),
|
|
Wire(Tx1),
|
|
}
|
|
pub struct Rx1(OwnedReadHalf);
|
|
pub struct Tx1(OwnedWriteHalf);
|
|
|
|
impl crate::Bind for Bind {
|
|
type R = Rx1;
|
|
type T = Tx1;
|
|
async fn wait(&self) -> Result<(<Self as crate::Bind>::R, <Self as crate::Bind>::T), String> {
|
|
let (con, _) = self
|
|
.0
|
|
.accept()
|
|
.await
|
|
.map_err(|e| format!("[tcp] accepting a new connection failed: {e}"))?;
|
|
let (rx, tx) = con.into_split();
|
|
Ok((Rx1(rx), Tx1(tx)))
|
|
}
|
|
}
|
|
impl crate::Wire for Bind {
|
|
type R = Rx1;
|
|
type T = Tx1;
|
|
async fn parse(arg: &str) -> Result<Self, String> {
|
|
let addr = arg;
|
|
Ok(Self(TcpListener::bind(addr).await.map_err(|e| {
|
|
format!("[tcp] binding to `{addr}` failed: {e}")
|
|
})?))
|
|
}
|
|
async fn open(&self) -> Result<(Self::R, Self::T), String> {
|
|
Err("using binds as wires is not (yet) supported for tcp".to_owned())
|
|
}
|
|
}
|
|
impl crate::Wire for Wire {
|
|
type R = Rx1;
|
|
type T = Tx1;
|
|
async fn parse(arg: &str) -> Result<Self, String> {
|
|
Ok(Self(arg.to_owned()))
|
|
}
|
|
async fn open(&self) -> Result<(Self::R, Self::T), String> {
|
|
let (rx, tx) = TcpStream::connect(&self.0)
|
|
.await
|
|
.map_err(|e| format!("[tcp] connecting to `{}` failed: {e}", &self.0))?
|
|
.into_split();
|
|
Ok((Rx1(rx), Tx1(tx)))
|
|
}
|
|
}
|
|
|
|
impl crate::Rx for Rx1 {
|
|
type T<'a> = &'a [u8];
|
|
|
|
async fn rx<'a>(&mut self, buf: &'a mut [u8]) -> Result<Self::T<'a>, String> {
|
|
let i = self
|
|
.0
|
|
.read(buf)
|
|
.await
|
|
.map_err(|e| format!("[tcp] reading bytes failed: {e}"))?;
|
|
Ok(&buf[..i])
|
|
}
|
|
}
|
|
impl crate::Tx for Tx1 {
|
|
async fn tx(&mut self, buf: &[u8]) -> Result<(), String> {
|
|
self.0
|
|
.write_all(buf)
|
|
.await
|
|
.map_err(|e| format!("[tcp] writing bytes failed: {e}"))
|
|
}
|
|
}
|