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;