use crate::error::TransportError;
use crate::protocols::tcp::connection::TcpTransportStream;
use crate::transport::{Transport, TransportClient, TransportStream};
use async_trait::async_trait;
use std::net::SocketAddr;
use tokio::io::AsyncWriteExt;
use tokio::net::TcpStream;
pub struct TcpClient {
connection: Option<TcpTransportStream>,
}
impl TcpClient {
pub fn new() -> Self {
Self { connection: None }
}
}
#[async_trait]
impl Transport for TcpClient {
async fn connect(&mut self, addr: SocketAddr) -> Result<(), TransportError> {
let stream = TcpStream::connect(addr).await.map_err(|e| {
TransportError::ConnectionError(format!("Failed to connect to {}: {}", addr, e))
})?;
self.connection = Some(TcpTransportStream::new(stream));
println!("Connected to {}", addr);
Ok(())
}
async fn disconnect(&mut self) -> Result<(), TransportError> {
if let Some(ref mut conn) = self.connection {
conn.stream.shutdown().await.map_err(|e| {
TransportError::DisconnectError(format!("Failed to disconnect: {}", e))
})?;
println!("Disconnected from the server");
} else {
return Err(TransportError::DisconnectError(
"No active connection".to_string(),
));
}
self.connection = None;
Ok(())
}
}
#[async_trait]
impl TransportClient for TcpClient {
fn stream(&mut self) -> &mut dyn TransportStream {
self.connection
.as_mut()
.expect("Connection not established")
}
}