|
|
|
@ -2,11 +2,11 @@ use super::{Interest, Ready, Reconnectable};
|
|
|
|
|
use async_trait::async_trait;
|
|
|
|
|
use std::io;
|
|
|
|
|
|
|
|
|
|
mod framed;
|
|
|
|
|
pub use framed::*;
|
|
|
|
|
/* mod framed;
|
|
|
|
|
pub use framed::*; */
|
|
|
|
|
|
|
|
|
|
mod inmemory;
|
|
|
|
|
pub use inmemory::*;
|
|
|
|
|
/* mod inmemory;
|
|
|
|
|
pub use inmemory::*; */
|
|
|
|
|
|
|
|
|
|
mod tcp;
|
|
|
|
|
pub use tcp::*;
|
|
|
|
@ -14,6 +14,9 @@ pub use tcp::*;
|
|
|
|
|
#[cfg(unix)]
|
|
|
|
|
mod unix;
|
|
|
|
|
|
|
|
|
|
#[cfg(unix)]
|
|
|
|
|
pub use unix::*;
|
|
|
|
|
|
|
|
|
|
#[cfg(windows)]
|
|
|
|
|
mod windows;
|
|
|
|
|
|
|
|
|
@ -54,4 +57,71 @@ pub trait RawTransport: Reconnectable {
|
|
|
|
|
let _ = self.ready(Interest::WRITABLE).await?;
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Reads exactly `n` bytes where `n` is the length of `buf` by continuing to call [`try_read`]
|
|
|
|
|
/// until completed. Calls to [`readable`] are made to ensure the transport is ready. Returns
|
|
|
|
|
/// the total bytes read.
|
|
|
|
|
///
|
|
|
|
|
/// [`try_read`]: RawTransport::try_read
|
|
|
|
|
/// [`readable`]: RawTransport::readable
|
|
|
|
|
async fn read_exact(&self, buf: &mut [u8]) -> io::Result<usize> {
|
|
|
|
|
let mut i = 0;
|
|
|
|
|
|
|
|
|
|
while i < buf.len() {
|
|
|
|
|
self.readable().await?;
|
|
|
|
|
|
|
|
|
|
match self.try_read(&mut buf[i..]) {
|
|
|
|
|
// If we get 0 bytes read, this usually means that the underlying reader
|
|
|
|
|
// has closed, so we will return an EOF error to reflect that
|
|
|
|
|
//
|
|
|
|
|
// NOTE: `try_read` can also return 0 if the buf len is zero, but because we check
|
|
|
|
|
// that our index is < len, the situation where we call try_read with a buf
|
|
|
|
|
// of len 0 will never happen
|
|
|
|
|
Ok(0) => return Err(io::Error::from(io::ErrorKind::UnexpectedEof)),
|
|
|
|
|
|
|
|
|
|
Ok(n) => i += n,
|
|
|
|
|
|
|
|
|
|
// Because we are using `try_read`, it can be possible for it to return
|
|
|
|
|
// WouldBlock; so, if we encounter that then we just wait for next readable
|
|
|
|
|
Err(x) if x.kind() == io::ErrorKind::WouldBlock => continue,
|
|
|
|
|
|
|
|
|
|
Err(x) => return Err(x),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(i)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Writes all of `buf` by continuing to call [`try_write`] until completed. Calls to
|
|
|
|
|
/// [`writeable`] are made to ensure the transport is ready.
|
|
|
|
|
///
|
|
|
|
|
/// [`try_write`]: RawTransport::try_write
|
|
|
|
|
/// [`writable`]: RawTransport::writable
|
|
|
|
|
async fn write_all(&self, buf: &[u8]) -> io::Result<()> {
|
|
|
|
|
let mut i = 0;
|
|
|
|
|
|
|
|
|
|
while i < buf.len() {
|
|
|
|
|
self.writeable().await?;
|
|
|
|
|
|
|
|
|
|
match self.try_write(&buf[i..]) {
|
|
|
|
|
// If we get 0 bytes written, this usually means that the underlying writer
|
|
|
|
|
// has closed, so we will return a broken pipe error to reflect that
|
|
|
|
|
//
|
|
|
|
|
// NOTE: `try_write` can also return 0 if the buf len is zero, but because we check
|
|
|
|
|
// that our index is < len, the situation where we call try_write with a buf
|
|
|
|
|
// of len 0 will never happen
|
|
|
|
|
Ok(0) => return Err(io::Error::from(io::ErrorKind::BrokenPipe)),
|
|
|
|
|
|
|
|
|
|
Ok(n) => i += n,
|
|
|
|
|
|
|
|
|
|
// Because we are using `try_write`, it can be possible for it to return
|
|
|
|
|
// WouldBlock; so, if we encounter that then we just wait for next writeable
|
|
|
|
|
Err(x) if x.kind() == io::ErrorKind::WouldBlock => continue,
|
|
|
|
|
|
|
|
|
|
Err(x) => return Err(x),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|