#![doc(html_root_url = "https://docs.rs/socket2/0.4")]
#![deny(missing_docs, missing_debug_implementations, rust_2018_idioms)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(test, deny(warnings))]
#![doc(test(attr(deny(warnings))))]
use std::fmt;
use std::mem::MaybeUninit;
use std::net::SocketAddr;
use std::ops::{Deref, DerefMut};
use std::time::Duration;
macro_rules! impl_debug {
(
// Type name for which to implement `fmt::Debug`.
$type: path,
$(
$(#[$target: meta])*
// The flag(s) to check.
$libc: ident :: $flag: ident
),+ $(,)*
) => {
impl std::fmt::Debug for $type {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let string = match self.0 {
$(
$(#[$target])*
$libc :: $flag => stringify!($flag),
)+
n => return write!(f, "{}", n),
};
f.write_str(string)
}
}
};
}
macro_rules! from {
($from: ty, $for: ty) => {
impl From<$from> for $for {
fn from(socket: $from) -> $for {
#[cfg(unix)]
unsafe {
<$for>::from_raw_fd(socket.into_raw_fd())
}
#[cfg(windows)]
unsafe {
<$for>::from_raw_socket(socket.into_raw_socket())
}
}
}
};
}
mod sockaddr;
mod socket;
mod sockref;
#[cfg_attr(unix, path = "sys/unix.rs")]
#[cfg_attr(windows, path = "sys/windows.rs")]
mod sys;
#[cfg(not(any(windows, unix)))]
compile_error!("Socket2 doesn't support the compile target");
use sys::c_int;
pub use sockaddr::SockAddr;
pub use socket::Socket;
pub use sockref::SockRef;
#[cfg(not(any(
target_os = "haiku",
target_os = "illumos",
target_os = "netbsd",
target_os = "redox",
target_os = "solaris",
)))]
pub use socket::InterfaceIndexOrAddress;
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct Domain(c_int);
impl Domain {
pub const IPV4: Domain = Domain(sys::AF_INET);
pub const IPV6: Domain = Domain(sys::AF_INET6);
pub const fn for_address(address: SocketAddr) -> Domain {
match address {
SocketAddr::V4(_) => Domain::IPV4,
SocketAddr::V6(_) => Domain::IPV6,
}
}
}
impl From<c_int> for Domain {
fn from(d: c_int) -> Domain {
Domain(d)
}
}
impl From<Domain> for c_int {
fn from(d: Domain) -> c_int {
d.0
}
}
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct Type(c_int);
impl Type {
pub const STREAM: Type = Type(sys::SOCK_STREAM);
pub const DGRAM: Type = Type(sys::SOCK_DGRAM);
#[cfg(feature = "all")]
#[cfg_attr(docsrs, doc(cfg(feature = "all")))]
pub const SEQPACKET: Type = Type(sys::SOCK_SEQPACKET);
#[cfg(all(feature = "all", not(target_os = "redox")))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "all", not(target_os = "redox")))))]
pub const RAW: Type = Type(sys::SOCK_RAW);
}
impl From<c_int> for Type {
fn from(t: c_int) -> Type {
Type(t)
}
}
impl From<Type> for c_int {
fn from(t: Type) -> c_int {
t.0
}
}
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct Protocol(c_int);
impl Protocol {
pub const ICMPV4: Protocol = Protocol(sys::IPPROTO_ICMP);
pub const ICMPV6: Protocol = Protocol(sys::IPPROTO_ICMPV6);
pub const TCP: Protocol = Protocol(sys::IPPROTO_TCP);
pub const UDP: Protocol = Protocol(sys::IPPROTO_UDP);
}
impl From<c_int> for Protocol {
fn from(p: c_int) -> Protocol {
Protocol(p)
}
}
impl From<Protocol> for c_int {
fn from(p: Protocol) -> c_int {
p.0
}
}
#[cfg(not(target_os = "redox"))]
#[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))]
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct RecvFlags(c_int);
#[cfg(not(target_os = "redox"))]
impl RecvFlags {
pub const fn is_truncated(self) -> bool {
self.0 & sys::MSG_TRUNC != 0
}
}
#[repr(transparent)]
pub struct MaybeUninitSlice<'a>(sys::MaybeUninitSlice<'a>);
impl<'a> fmt::Debug for MaybeUninitSlice<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self.0.as_slice(), fmt)
}
}
impl<'a> MaybeUninitSlice<'a> {
pub fn new(buf: &'a mut [MaybeUninit<u8>]) -> MaybeUninitSlice<'a> {
MaybeUninitSlice(sys::MaybeUninitSlice::new(buf))
}
}
impl<'a> Deref for MaybeUninitSlice<'a> {
type Target = [MaybeUninit<u8>];
fn deref(&self) -> &[MaybeUninit<u8>] {
self.0.as_slice()
}
}
impl<'a> DerefMut for MaybeUninitSlice<'a> {
fn deref_mut(&mut self) -> &mut [MaybeUninit<u8>] {
self.0.as_mut_slice()
}
}
#[derive(Debug, Clone)]
pub struct TcpKeepalive {
#[cfg_attr(target_os = "openbsd", allow(dead_code))]
time: Option<Duration>,
#[cfg(not(any(target_os = "openbsd", target_os = "redox", target_os = "solaris")))]
interval: Option<Duration>,
#[cfg(not(any(
target_os = "openbsd",
target_os = "redox",
target_os = "solaris",
target_os = "windows"
)))]
retries: Option<u32>,
}
impl TcpKeepalive {
pub const fn new() -> TcpKeepalive {
TcpKeepalive {
time: None,
#[cfg(not(any(target_os = "openbsd", target_os = "redox", target_os = "solaris")))]
interval: None,
#[cfg(not(any(
target_os = "openbsd",
target_os = "redox",
target_os = "solaris",
target_os = "windows"
)))]
retries: None,
}
}
pub const fn with_time(self, time: Duration) -> Self {
Self {
time: Some(time),
..self
}
}
#[cfg(all(
feature = "all",
any(
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "fuchsia",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
target_vendor = "apple",
windows,
)
))]
#[cfg_attr(
docsrs,
doc(cfg(all(
feature = "all",
any(
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "fuchsia",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
target_vendor = "apple",
windows,
)
)))
)]
pub const fn with_interval(self, interval: Duration) -> Self {
Self {
interval: Some(interval),
..self
}
}
#[cfg(all(
feature = "all",
any(
doc,
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "fuchsia",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
target_vendor = "apple",
)
))]
#[cfg_attr(
docsrs,
doc(cfg(all(
feature = "all",
any(
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "fuchsia",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
target_vendor = "apple",
)
)))
)]
pub const fn with_retries(self, retries: u32) -> Self {
Self {
retries: Some(retries),
..self
}
}
}