use super::raw::*;
use crate::backend::c;
use core::fmt;
use core::marker::PhantomData;
use core::mem::forget;
#[derive(Copy, Clone)]
#[repr(transparent)]
#[cfg_attr(staged_api, rustc_layout_scalar_valid_range_start(0))]
#[cfg_attr(
all(staged_api, target_pointer_width = "32"),
rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)
)]
#[cfg_attr(
all(staged_api, target_pointer_width = "64"),
rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE)
)]
#[cfg_attr(staged_api, rustc_nonnull_optimization_guaranteed)]
#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))]
pub struct BorrowedSocket<'socket> {
socket: RawSocket,
_phantom: PhantomData<&'socket OwnedSocket>,
}
#[repr(transparent)]
#[cfg_attr(staged_api, rustc_layout_scalar_valid_range_start(0))]
#[cfg_attr(
all(staged_api, target_pointer_width = "32"),
rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)
)]
#[cfg_attr(
all(staged_api, target_pointer_width = "64"),
rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE)
)]
#[cfg_attr(staged_api, rustc_nonnull_optimization_guaranteed)]
#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))]
pub struct OwnedSocket {
socket: RawSocket,
}
impl BorrowedSocket<'_> {
#[inline]
#[cfg_attr(
staged_api,
rustc_const_stable(feature = "io_safety", since = "1.63.0")
)]
#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))]
pub const unsafe fn borrow_raw(socket: RawSocket) -> Self {
assert!(socket != c::INVALID_SOCKET as RawSocket);
Self {
socket,
_phantom: PhantomData,
}
}
}
#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))]
impl AsRawSocket for BorrowedSocket<'_> {
#[inline]
fn as_raw_socket(&self) -> RawSocket {
self.socket
}
}
#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))]
impl AsRawSocket for OwnedSocket {
#[inline]
fn as_raw_socket(&self) -> RawSocket {
self.socket
}
}
#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))]
impl IntoRawSocket for OwnedSocket {
#[inline]
fn into_raw_socket(self) -> RawSocket {
let socket = self.socket;
forget(self);
socket
}
}
#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))]
impl FromRawSocket for OwnedSocket {
#[inline]
unsafe fn from_raw_socket(socket: RawSocket) -> Self {
debug_assert_ne!(socket, c::INVALID_SOCKET as RawSocket);
Self { socket }
}
}
#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))]
impl Drop for OwnedSocket {
#[inline]
fn drop(&mut self) {
unsafe {
let _ = c::closesocket(self.socket as c::SOCKET);
}
}
}
#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))]
impl fmt::Debug for BorrowedSocket<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("BorrowedSocket")
.field("socket", &self.socket)
.finish()
}
}
#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))]
impl fmt::Debug for OwnedSocket {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OwnedSocket")
.field("socket", &self.socket)
.finish()
}
}
#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))]
pub trait AsSocket {
#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))]
fn as_socket(&self) -> BorrowedSocket<'_>;
}
#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))]
impl<T: AsSocket> AsSocket for &T {
#[inline]
fn as_socket(&self) -> BorrowedSocket<'_> {
T::as_socket(self)
}
}
#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))]
impl<T: AsSocket> AsSocket for &mut T {
#[inline]
fn as_socket(&self) -> BorrowedSocket<'_> {
T::as_socket(self)
}
}
#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))]
impl AsSocket for BorrowedSocket<'_> {
#[inline]
fn as_socket(&self) -> BorrowedSocket<'_> {
*self
}
}
#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))]
impl AsSocket for OwnedSocket {
#[inline]
fn as_socket(&self) -> BorrowedSocket<'_> {
unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
}
}