use std::fmt;
use std::marker::PhantomData;
use std::mem::ManuallyDrop;
use std::ops::Deref;
#[cfg(unix)]
use std::os::unix::io::{AsRawFd, FromRawFd};
#[cfg(windows)]
use std::os::windows::io::{AsRawSocket, FromRawSocket};
use crate::Socket;
pub struct SockRef<'s> {
socket: ManuallyDrop<Socket>,
_lifetime: PhantomData<&'s Socket>,
}
impl<'s> Deref for SockRef<'s> {
type Target = Socket;
fn deref(&self) -> &Self::Target {
&self.socket
}
}
#[cfg(unix)]
impl<'s, S> From<&'s S> for SockRef<'s>
where
S: AsRawFd,
{
fn from(socket: &'s S) -> Self {
SockRef {
socket: ManuallyDrop::new(unsafe { Socket::from_raw_fd(socket.as_raw_fd()) }),
_lifetime: PhantomData,
}
}
}
#[cfg(windows)]
impl<'s, S> From<&'s S> for SockRef<'s>
where
S: AsRawSocket,
{
fn from(socket: &'s S) -> Self {
SockRef {
socket: ManuallyDrop::new(unsafe { Socket::from_raw_socket(socket.as_raw_socket()) }),
_lifetime: PhantomData,
}
}
}
impl fmt::Debug for SockRef<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SockRef")
.field("raw", &self.socket.inner)
.field("local_addr", &self.socket.local_addr().ok())
.field("peer_addr", &self.socket.peer_addr().ok())
.finish()
}
}