use core::time::Duration;
use std::io;
use liminal_server::server::connection::LoopbackClientEnd;
use super::super::framing::{FrameStream, IO_TIMEOUT};
#[derive(Debug)]
pub(super) struct LoopbackStream {
end: LoopbackClientEnd,
read_deadline: Duration,
}
impl LoopbackStream {
pub(super) const fn new(end: LoopbackClientEnd) -> Self {
Self {
end,
read_deadline: IO_TIMEOUT,
}
}
}
impl FrameStream for LoopbackStream {
fn read_bytes(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.end.read_timeout(buf, Some(self.read_deadline))
}
fn write_all_bytes(&mut self, bytes: &[u8]) -> io::Result<()> {
let mut remaining = bytes;
while !remaining.is_empty() {
let written = self.end.write_timeout(remaining, Some(IO_TIMEOUT))?;
if written == 0 {
return Err(io::Error::new(
io::ErrorKind::WriteZero,
"loopback ring accepted no bytes",
));
}
let Some(rest) = remaining.get(written..) else {
return Err(io::Error::other(
"loopback write reported more bytes than were offered",
));
};
remaining = rest;
}
Ok(())
}
fn flush_bytes(&mut self) -> io::Result<()> {
Ok(())
}
fn set_read_deadline(&mut self, timeout: Duration) -> io::Result<()> {
self.read_deadline = timeout;
Ok(())
}
}