use crate::{Error, Fd, InvalidState, Result};
use alloc::vec::Vec;
mod buffered;
pub use buffered::BufConnection;
cfg_std_unix! {
mod sendmsg;
pub use sendmsg::SendmsgConnection;
}
cfg_test! {
mod test;
pub(crate) use test::with_test_connection;
}
cfg_std! {
pub(crate) type IoSlice<'a> = std::io::IoSlice<'a>;
pub(crate) type IoSliceMut<'a> = std::io::IoSliceMut<'a>;
mod std_wrapper;
pub use std_wrapper::StdConnection;
}
cfg_no_std! {
pub(crate) type IoSlice<'a> = &'a [u8];
pub(crate) type IoSliceMut<'a> = &'a mut [u8];
}
pub trait Connection {
fn send_slices_and_fds(&mut self, slices: &[IoSlice<'_>], fds: &mut Vec<Fd>) -> Result<usize>;
fn send_slices(&mut self, slices: &[IoSlice<'_>]) -> Result<usize> {
self.send_slices_and_fds(slices, &mut Vec::new())
}
fn send_slice(&mut self, slice: &[u8]) -> Result<usize> {
self.send_slices(&[new_io_slice(slice)])
}
fn recv_slices_and_fds(
&mut self,
slices: &mut [IoSliceMut<'_>],
fds: &mut Vec<Fd>,
) -> Result<usize>;
fn recv_slice_and_fds(&mut self, slice: &mut [u8], fds: &mut Vec<Fd>) -> Result<usize> {
self.recv_slices_and_fds(&mut [new_io_slice_mut(slice)], fds)
}
fn recv_slice(&mut self, slice: &mut [u8]) -> Result<usize> {
let mut fds = Vec::new();
let result = self.recv_slice_and_fds(slice, &mut fds);
if fds.is_empty() {
result
} else {
Err(Error::make_invalid_state(InvalidState::UnexpectedFds))
}
}
fn flush(&mut self) -> Result<()>;
fn non_blocking_recv_slices_and_fds(
&mut self,
slices: &mut [IoSliceMut<'_>],
fds: &mut Vec<Fd>,
) -> Result<usize>;
fn non_blocking_recv_slice_and_fds(
&mut self,
slice: &mut [u8],
fds: &mut Vec<Fd>,
) -> Result<usize> {
self.non_blocking_recv_slices_and_fds(&mut [new_io_slice_mut(slice)], fds)
}
fn shutdown(&self) -> Result<()>;
}
impl<C: Connection + ?Sized> Connection for &mut C {
fn send_slices_and_fds(&mut self, slices: &[IoSlice<'_>], fds: &mut Vec<Fd>) -> Result<usize> {
(**self).send_slices_and_fds(slices, fds)
}
fn send_slices(&mut self, slices: &[IoSlice<'_>]) -> Result<usize> {
(**self).send_slices(slices)
}
fn send_slice(&mut self, slice: &[u8]) -> Result<usize> {
(**self).send_slice(slice)
}
fn recv_slices_and_fds(
&mut self,
slices: &mut [IoSliceMut<'_>],
fds: &mut Vec<Fd>,
) -> Result<usize> {
(**self).recv_slices_and_fds(slices, fds)
}
fn recv_slice_and_fds(&mut self, slice: &mut [u8], fds: &mut Vec<Fd>) -> Result<usize> {
(**self).recv_slice_and_fds(slice, fds)
}
fn recv_slice(&mut self, slice: &mut [u8]) -> Result<usize> {
(**self).recv_slice(slice)
}
fn flush(&mut self) -> Result<()> {
(**self).flush()
}
fn non_blocking_recv_slices_and_fds(
&mut self,
slices: &mut [IoSliceMut<'_>],
fds: &mut Vec<Fd>,
) -> Result<usize> {
(**self).non_blocking_recv_slices_and_fds(slices, fds)
}
fn non_blocking_recv_slice_and_fds(
&mut self,
slice: &mut [u8],
fds: &mut Vec<Fd>,
) -> Result<usize> {
(**self).non_blocking_recv_slice_and_fds(slice, fds)
}
fn shutdown(&self) -> Result<()> {
(**self).shutdown()
}
}
cfg_std! {
pub(crate) fn new_io_slice(sl: &[u8]) -> IoSlice<'_> {
IoSlice::new(sl)
}
pub(crate) fn new_io_slice_mut(sl: &mut [u8]) -> IoSliceMut<'_> {
IoSliceMut::new(sl)
}
pub(crate) fn advance_io(sl: &mut IoSlice<'_>, bytes: usize) {
advance::advance(sl, bytes);
}
}
cfg_no_std! {
pub(crate) fn new_io_slice(sl: &[u8]) -> IoSlice<'_> {
sl
}
pub(crate) fn new_io_slice_mut(sl: &mut [u8]) -> IoSliceMut<'_> {
sl
}
pub(crate) fn advance_io(sl: &mut IoSlice<'_>, bytes: usize) {
*sl = &sl[bytes..];
}
}