use compio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
use compio::time::timeout;
use std::io;
use std::time::Duration;
pub async fn read_exact_with_timeout<S, B>(
stream: &mut S,
buf: B,
duration: Option<Duration>,
) -> io::Result<compio::buf::BufResult<(), B>>
where
S: AsyncRead + Unpin,
B: compio::buf::IoBufMut,
{
match duration {
None => {
Ok(stream.read_exact(buf).await)
}
Some(d) if d.is_zero() => {
Err(io::Error::new(
io::ErrorKind::WouldBlock,
"Non-blocking mode not yet implemented",
))
}
Some(d) => {
match timeout(d, stream.read_exact(buf)).await {
Ok(result) => Ok(result),
Err(_elapsed) => Err(io::Error::new(
io::ErrorKind::TimedOut,
"Read operation timed out",
)),
}
}
}
}
pub async fn write_all_with_timeout<S, B>(
stream: &mut S,
buf: B,
duration: Option<Duration>,
) -> io::Result<compio::buf::BufResult<(), B>>
where
S: AsyncWrite + Unpin,
B: compio::buf::IoBuf,
{
match duration {
None => {
Ok(stream.write_all(buf).await)
}
Some(d) if d.is_zero() => {
Err(io::Error::new(
io::ErrorKind::WouldBlock,
"Non-blocking mode not yet implemented",
))
}
Some(d) => {
match timeout(d, stream.write_all(buf)).await {
Ok(result) => Ok(result),
Err(_elapsed) => Err(io::Error::new(
io::ErrorKind::TimedOut,
"Write operation timed out",
)),
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_timeout_types() {
let infinite: Option<Duration> = None;
assert!(infinite.is_none());
let nonblocking = Some(Duration::ZERO);
assert_eq!(nonblocking, Some(Duration::ZERO));
let timed = Some(Duration::from_secs(5));
assert_eq!(timed, Some(Duration::from_secs(5)));
}
}