use crate::NetworkAddress;
use avila_error::{Error, ErrorKind, Result};
use tokio::net::{TcpListener, TcpStream};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
pub struct TcpServer {
listener: TcpListener,
address: NetworkAddress,
}
impl TcpServer {
pub async fn bind(address: NetworkAddress) -> Result<Self> {
let listener = TcpListener::bind(address.to_string())
.await
.map_err(|e| Error::new(ErrorKind::Network, format!("Falha ao vincular TCP: {}", e)))?;
Ok(Self { listener, address })
}
pub async fn accept(&self) -> Result<(TcpStream, std::net::SocketAddr)> {
self.listener
.accept()
.await
.map_err(|e| Error::new(ErrorKind::Network, format!("Falha ao aceitar conexão: {}", e)))
}
pub fn address(&self) -> &NetworkAddress {
&self.address
}
}
pub struct TcpClient {
stream: TcpStream,
}
impl TcpClient {
pub async fn connect(address: NetworkAddress) -> Result<Self> {
let stream = TcpStream::connect(address.to_string())
.await
.map_err(|e| Error::new(ErrorKind::Network, format!("Falha ao conectar: {}", e)))?;
Ok(Self { stream })
}
pub async fn send(&mut self, data: &[u8]) -> Result<()> {
self.stream
.write_all(data)
.await
.map_err(|e| Error::new(ErrorKind::Io, format!("Falha ao enviar: {}", e)))
}
pub async fn receive(&mut self, buffer: &mut [u8]) -> Result<usize> {
self.stream
.read(buffer)
.await
.map_err(|e| Error::new(ErrorKind::Io, format!("Falha ao receber: {}", e)))
}
}