summaryrefslogtreecommitdiff
path: root/src/conn.rs
blob: b5224d1abe85ad1339ce15b977833a6436fbb13f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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)))
}

/*

#[cfg(feature = "server")]
pub struct RemoteClt;

#[cfg(feature = "server")]
impl Remote for RemoteClt {
    type Sender = mt_rudp::ToClt;
    type To = crate::ToCltPkt;
    type From = crate::ToSrvPkt;
}

*/

#[derive(Debug)]
pub struct MtSender<R: Remote>(pub mt_rudp::RudpSender<R::UdpSender>);

#[derive(Debug)]
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(())
    }
}

// derive(Clone) adds unwanted trait bound to R
impl<R: Remote> Clone for MtSender<R> {
    fn clone(&self) -> Self {
        Self(self.0.clone())
    }
}