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
use crate::enc::{EnetDecoder, EnetDecoderError, EnetEncoder, EnetEncoderError};
use enet_proto::{RequestEnvelope, Response};
use futures::{SinkExt, StreamExt};
use thiserror::Error;
use tokio::{
io,
net::{
tcp::{OwnedReadHalf, OwnedWriteHalf},
TcpStream, ToSocketAddrs,
},
};
use tokio_util::codec::{FramedRead, FramedWrite};
use tracing::instrument;
pub(crate) struct Connection {
reader: FramedRead<OwnedReadHalf, EnetDecoder>,
writer: FramedWrite<OwnedWriteHalf, EnetEncoder>,
}
impl Connection {
pub(crate) async fn new(addr: impl ToSocketAddrs) -> Result<Self, ConnectError> {
let stream = TcpStream::connect(addr).await?;
let (reader, writer) = stream.into_split();
Ok(Self {
reader: FramedRead::new(reader, EnetDecoder::new()),
writer: FramedWrite::new(writer, EnetEncoder::new()),
})
}
#[instrument(level = "debug", target = "enet-client::con", skip(self, message), err)]
pub(crate) async fn send(&mut self, message: &RequestEnvelope) -> Result<(), SendError> {
Ok(self.writer.send(message).await?)
}
#[instrument(level = "debug", target = "enet-client::con", skip(self), err)]
pub(crate) async fn recv(&mut self) -> Result<Response, RecvError> {
match self.reader.next().await {
Some(result) => Ok(result?),
None => bail!(ConnectionClosed),
}
}
}
#[non_exhaustive]
#[derive(Debug, Error)]
#[error("Failed to connect to gateway.")]
pub enum ConnectError {
FailedToConnect(#[from] io::Error),
}
#[non_exhaustive]
#[derive(Debug, Error)]
#[error("Failed to send message.")]
pub enum SendError {
FailedToSend(#[from] EnetEncoderError),
}
#[non_exhaustive]
#[derive(Debug, Error)]
#[error("Failed to receive response.")]
pub enum RecvError {
DecoderError(#[from] EnetDecoderError),
Closed(#[from] ConnectionClosed),
}
#[derive(Debug, Error)]
#[error("Connection closed.")]
pub struct ConnectionClosed;