]> git.lizzy.rs Git - mt_net.git/blob - src/conn.rs
Implement Clone for MtSender
[mt_net.git] / src / conn.rs
1 use super::PktInfo;
2 use delegate::delegate;
3 use mt_ser::{DefCfg, MtDeserialize, MtSerialize};
4 use std::{borrow::Cow, io};
5 use thiserror::Error;
6
7 pub trait Remote {
8     type UdpSender: mt_rudp::UdpSender;
9     type PktFrom: MtDeserialize;
10     type PktTo: MtSerialize + PktInfo;
11 }
12
13 #[cfg(feature = "client")]
14 pub struct RemoteSrv;
15
16 #[cfg(feature = "client")]
17 impl Remote for RemoteSrv {
18     type UdpSender = mt_rudp::ToSrv;
19     type PktTo = crate::ToSrvPkt;
20     type PktFrom = crate::ToCltPkt;
21 }
22
23 #[cfg(feature = "client")]
24 pub async fn connect(addr: &str) -> io::Result<(MtSender<RemoteSrv>, MtReceiver<RemoteSrv>)> {
25     let (tx, rx) = mt_rudp::connect(addr).await?;
26     Ok((MtSender(tx), MtReceiver(rx)))
27 }
28
29 /*
30
31 #[cfg(feature = "server")]
32 pub struct RemoteClt;
33
34 #[cfg(feature = "server")]
35 impl Remote for RemoteClt {
36     type Sender = mt_rudp::ToClt;
37     type To = crate::ToCltPkt;
38     type From = crate::ToSrvPkt;
39 }
40
41 */
42
43 #[derive(Debug)]
44 pub struct MtSender<R: Remote>(pub mt_rudp::RudpSender<R::UdpSender>);
45
46 #[derive(Debug)]
47 pub struct MtReceiver<R: Remote>(pub mt_rudp::RudpReceiver<R::UdpSender>);
48
49 #[derive(Error, Debug)]
50 pub enum RecvError {
51     #[error("connection error: {0}")]
52     ConnError(#[from] mt_rudp::Error),
53     #[error("deserialize error: {0}")]
54     DeserializeError(#[from] mt_ser::DeserializeError),
55 }
56
57 #[derive(Error, Debug)]
58 pub enum SendError {
59     #[error("connection error: {0}")]
60     ConnError(#[from] io::Error),
61     #[error("serialize error: {0}")]
62     SerializeError(#[from] mt_ser::SerializeError),
63 }
64
65 macro_rules! impl_delegate {
66     ($T:ident) => {
67         impl<R: Remote> $T<R> {
68             delegate! {
69                 to self.0 {
70                     pub async fn peer_id(&self) -> u16;
71                     pub async fn is_server(&self) -> bool;
72                     pub async fn close(self);
73                 }
74             }
75         }
76     };
77 }
78
79 impl_delegate!(MtSender);
80 impl_delegate!(MtReceiver);
81
82 impl<R: Remote> MtReceiver<R> {
83     pub async fn recv(&mut self) -> Option<Result<R::PktFrom, RecvError>> {
84         self.0.recv().await.map(|res| {
85             res.map_err(RecvError::from).and_then(|pkt| {
86                 // TODO: warn on trailing data
87                 R::PktFrom::mt_deserialize::<DefCfg>(&mut io::Cursor::new(pkt.data))
88                     .map_err(RecvError::from)
89             })
90         })
91     }
92 }
93
94 impl<R: Remote> MtSender<R> {
95     pub async fn send(&self, pkt: &R::PktTo) -> Result<(), SendError> {
96         let mut writer = Vec::new();
97         pkt.mt_serialize::<DefCfg>(&mut writer)?;
98
99         let (chan, unrel) = pkt.pkt_info();
100         self.0
101             .send(mt_rudp::Pkt {
102                 chan,
103                 unrel,
104                 data: Cow::Borrowed(&writer),
105             })
106             .await?;
107
108         Ok(())
109     }
110 }
111
112 // derive(Clone) adds unwanted trait bound to R
113 impl<R: Remote> Clone for MtSender<R> {
114     fn clone(&self) -> Self {
115         Self(self.0.clone())
116     }
117 }