diff options
author | Lizzy Fleckenstein <eliasfleckenstein@web.de> | 2023-02-15 23:44:21 +0100 |
---|---|---|
committer | Lizzy Fleckenstein <eliasfleckenstein@web.de> | 2023-02-15 23:54:40 +0100 |
commit | 58f9e0a0005aab59dfd987bddb09952f3a5c195b (patch) | |
tree | 3809aeb1459d86edba39942767ddace0501e83d2 /src/conn.rs | |
parent | 03b44a9e68f76a9e0aa612b9597cc879bbc37157 (diff) | |
download | mt_net-58f9e0a0005aab59dfd987bddb09952f3a5c195b.tar.xz |
Add wrappers around mt_rudp
Diffstat (limited to 'src/conn.rs')
-rw-r--r-- | src/conn.rs | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/conn.rs b/src/conn.rs new file mode 100644 index 0000000..3fc0e55 --- /dev/null +++ b/src/conn.rs @@ -0,0 +1,104 @@ +use super::PktInfo; +use delegate::delegate; +use mt_ser::{DefCfg, MtDeserialize, MtSerialize}; +use std::{borrow::Cow, io}; +use thiserror::Error; + +pub trait Remote { + type UdpSender: mt_rudp::UdpSender; + type PktFrom: MtDeserialize; + type PktTo: MtSerialize + PktInfo; +} + +#[cfg(feature = "client")] +pub struct RemoteSrv; + +#[cfg(feature = "client")] +impl Remote for RemoteSrv { + type UdpSender = mt_rudp::ToSrv; + type PktTo = crate::ToSrvPkt; + type PktFrom = crate::ToCltPkt; +} + +#[cfg(feature = "client")] +pub async fn connect(addr: &str) -> io::Result<(MtSender<RemoteSrv>, MtReceiver<RemoteSrv>)> { + let (tx, rx) = mt_rudp::connect(addr).await?; + Ok((MtSender(tx), MtReceiver(rx))) +} + +/* + +pub struct RemoteClt; +impl Remote for RemoteClt { + type Sender = mt_rudp::ToClt; + type To = crate::ToCltPkt; + type From = crate::ToSrvPkt; +} + +*/ + +pub struct MtSender<R: Remote>(pub mt_rudp::RudpSender<R::UdpSender>); +pub struct MtReceiver<R: Remote>(pub mt_rudp::RudpReceiver<R::UdpSender>); + +#[derive(Error, Debug)] +pub enum RecvError { + #[error("connection error: {0}")] + ConnError(#[from] mt_rudp::Error), + #[error("deserialize error: {0}")] + DeserializeError(#[from] mt_ser::DeserializeError), +} + +#[derive(Error, Debug)] +pub enum SendError { + #[error("connection error: {0}")] + ConnError(#[from] io::Error), + #[error("serialize error: {0}")] + SerializeError(#[from] mt_ser::SerializeError), +} + +macro_rules! impl_delegate { + ($T:ident) => { + impl<R: Remote> $T<R> { + delegate! { + to self.0 { + pub async fn peer_id(&self) -> u16; + pub async fn is_server(&self) -> bool; + pub async fn close(self); + } + } + } + }; +} + +impl_delegate!(MtSender); +impl_delegate!(MtReceiver); + +impl<R: Remote> MtReceiver<R> { + pub async fn recv(&mut self) -> Option<Result<R::PktFrom, RecvError>> { + self.0.recv().await.map(|res| { + res.map_err(RecvError::from).and_then(|pkt| { + // TODO: warn on trailing data + R::PktFrom::mt_deserialize::<DefCfg>(&mut io::Cursor::new(pkt.data)) + .map_err(RecvError::from) + }) + }) + } +} + +impl<R: Remote> MtSender<R> { + pub async fn send(&self, pkt: &R::PktTo) -> Result<(), SendError> { + let mut writer = Vec::new(); + pkt.mt_serialize::<DefCfg>(&mut writer)?; + + let (chan, unrel) = pkt.pkt_info(); + self.0 + .send(mt_rudp::Pkt { + chan, + unrel, + data: Cow::Borrowed(&writer), + }) + .await?; + + Ok(()) + } +} |