use core::future::Future;
#[cfg(feature = "std")]
use std::os::fd::{AsFd, OwnedFd};
pub trait Socket: core::fmt::Debug {
type ReadHalf: ReadHalf;
type WriteHalf: WriteHalf;
const CAN_TRANSFER_FDS: bool = false;
fn split(self) -> (Self::ReadHalf, Self::WriteHalf);
}
pub trait ReadHalf: core::fmt::Debug {
fn read(&mut self, buf: &mut [u8]) -> impl Future<Output = crate::Result<ReadResult>>;
}
pub trait WriteHalf: core::fmt::Debug {
fn write(
&mut self,
buf: &[u8],
#[cfg(feature = "std")] fds: &[impl AsFd],
#[cfg(all(feature = "std", target_os = "linux"))] credentials: Option<
&crate::connection::PassedCredentials,
>,
) -> impl Future<Output = crate::Result<()>>;
}
#[cfg(feature = "std")]
pub trait FetchPeerCredentials {
fn fetch_peer_credentials(&self) -> impl Future<Output = std::io::Result<super::Credentials>>;
}
#[cfg(feature = "std")]
pub trait UnixSocket: AsFd {}
#[cfg(feature = "std")]
impl<T> FetchPeerCredentials for T
where
T: UnixSocket,
{
async fn fetch_peer_credentials(&self) -> std::io::Result<super::Credentials> {
crate::unix_utils::get_peer_credentials(self)
}
}
#[doc(hidden)]
pub mod impl_for_doc {
#[derive(Debug)]
pub struct Socket;
impl super::Socket for Socket {
type ReadHalf = ReadHalf;
type WriteHalf = WriteHalf;
fn split(self) -> (Self::ReadHalf, Self::WriteHalf) {
(ReadHalf, WriteHalf)
}
}
#[derive(Debug)]
pub struct ReadHalf;
impl super::ReadHalf for ReadHalf {
async fn read(&mut self, _buf: &mut [u8]) -> crate::Result<super::ReadResult> {
unreachable!("This is only for doc tests")
}
}
#[derive(Debug)]
pub struct WriteHalf;
impl super::WriteHalf for WriteHalf {
async fn write(
&mut self,
_buf: &[u8],
#[cfg(feature = "std")] _fds: &[impl super::AsFd],
#[cfg(all(feature = "std", target_os = "linux"))] _credentials: Option<
&crate::connection::PassedCredentials,
>,
) -> crate::Result<()> {
unreachable!("This is only for doc tests")
}
}
}
#[derive(Debug)]
pub struct ReadResult {
bytes_read: usize,
#[cfg(feature = "std")]
fds: alloc::vec::Vec<OwnedFd>,
#[cfg(all(feature = "std", target_os = "linux"))]
credentials: Option<crate::connection::PassedCredentials>,
}
impl ReadResult {
#[doc(hidden)]
pub fn new(bytes_read: usize) -> Self {
Self {
bytes_read,
#[cfg(feature = "std")]
fds: vec![],
#[cfg(all(feature = "std", target_os = "linux"))]
credentials: None,
}
}
pub fn bytes_read(&self) -> usize {
self.bytes_read
}
#[cfg(feature = "std")]
pub fn fds(&self) -> &[OwnedFd] {
&self.fds
}
#[cfg(all(feature = "std", target_os = "linux"))]
pub fn credentials(&self) -> Option<&crate::connection::PassedCredentials> {
self.credentials.as_ref()
}
#[cfg(feature = "std")]
#[doc(hidden)]
pub fn set_fds<F>(mut self, fds: F) -> Self
where
F: Into<alloc::vec::Vec<OwnedFd>>,
{
self.fds = fds.into();
self
}
#[cfg(all(feature = "std", target_os = "linux"))]
#[doc(hidden)]
pub fn set_credentials(
mut self,
credentials: Option<crate::connection::PassedCredentials>,
) -> Self {
self.credentials = credentials;
self
}
#[cfg(feature = "std")]
pub fn take_fds(&mut self) -> alloc::vec::Vec<OwnedFd> {
core::mem::take(&mut self.fds)
}
#[cfg(feature = "std")]
pub fn into_fds(self) -> alloc::vec::Vec<OwnedFd> {
self.fds
}
#[cfg(all(feature = "std", target_os = "linux"))]
pub fn take_credentials(&mut self) -> Option<crate::connection::PassedCredentials> {
self.credentials.take()
}
#[cfg(all(feature = "std", target_os = "linux"))]
pub fn into_credentials(self) -> Option<crate::connection::PassedCredentials> {
self.credentials
}
}