use super::Transport; use crate::encoding::Message; use anyhow::Result; use log::debug; use std::str::FromStr; use tokio::{ io::{AsyncBufReadExt, AsyncWriteExt, BufReader, BufWriter}, net::{ tcp::{OwnedReadHalf, OwnedWriteHalf}, TcpStream, }, sync::Mutex, }; pub struct TcpTransport { write: Mutex>, read: Mutex>, } impl TcpTransport { pub async fn new(stream: TcpStream) -> Result { let (read, write) = stream.into_split(); Ok(Self { write: BufWriter::new(write).into(), read: BufReader::new(read).into(), }) } } impl Transport for TcpTransport { async fn recv(&self) -> Result { let mut g = self.read.lock().await; let mut message = String::new(); while !message.ends_with("\r\n\r\n") { g.read_line(&mut message).await?; } let mesg = Message::from_str(message.trim())?; debug!("<- {mesg}"); Ok(mesg) } async fn send(&self, request: Message) -> Result<()> { debug!("-> {request}"); let mut g = self.write.lock().await; g.write_all(format!("{request}").as_bytes()).await?; g.flush().await?; Ok(()) } }