use std::{
fmt::Debug,
io::{self, Read, Write},
};
use super::ReadWrite;
use crate::{net::Codec, result::Result, Error, Packet, MAX_SIZE_PACKET};
#[derive(Debug)]
pub struct Framed {
inner: Box<dyn ReadWrite>,
codec: Codec,
}
impl Framed {
pub fn new(inner: Box<dyn ReadWrite>, codec: Codec) -> Self {
Self { inner, codec }
}
pub fn read(&mut self) -> Result<Packet> {
loop {
if self.codec.reached_timeout() {
return Err(Error::Timeout(
"Timeout exceeded, no keepalive or packet received".into(),
));
}
let packet = self.codec.decode()?;
if let Some(keepalive) = self.codec.keepalive() {
tracing::debug!("Ping? Pong!");
self.write(keepalive)?;
}
if let Some(packet) = packet {
return Ok(packet);
}
let mut buf = [0u8; MAX_SIZE_PACKET];
match self.inner.read(&mut buf) {
Ok(0) => {
return Err(Error::Disconnected);
},
Ok(amt) => {
self.codec.feed(&buf[..amt]);
},
Err(e) => {
if e.kind() == io::ErrorKind::WouldBlock {
continue;
}
return Err(e.into());
},
}
}
}
pub fn write<P: Into<Packet>>(&mut self, packet: P) -> Result<()> {
let buf = self.codec.encode(&packet.into())?;
if !buf.is_empty() {
let _ = self.inner.write(&buf)?;
self.inner.flush()?;
}
Ok(())
}
}