use crate::net::{TcpStream, TcpListener};
use crate::sys;
use std::io;
use std::mem;
use std::net::SocketAddr;
#[cfg(unix)]
use std::os::unix::io::{AsRawFd, RawFd, FromRawFd};
#[cfg(windows)]
use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};
#[derive(Debug)]
pub struct TcpSocket {
sys: sys::tcp::TcpSocket,
}
impl TcpSocket {
pub fn new_v4() -> io::Result<TcpSocket> {
sys::tcp::new_v4_socket().map(|sys| TcpSocket {
sys
})
}
pub fn new_v6() -> io::Result<TcpSocket> {
sys::tcp::new_v6_socket().map(|sys| TcpSocket {
sys
})
}
pub(crate) fn new_for_addr(addr: SocketAddr) -> io::Result<TcpSocket> {
if addr.is_ipv4() {
TcpSocket::new_v4()
} else {
TcpSocket::new_v6()
}
}
pub fn bind(&self, addr: SocketAddr) -> io::Result<()> {
sys::tcp::bind(self.sys, addr)
}
pub fn connect(self, addr: SocketAddr) -> io::Result<TcpStream> {
let stream = sys::tcp::connect(self.sys, addr)?;
mem::forget(self);
Ok(TcpStream::from_std(stream))
}
pub fn listen(self, backlog: u32) -> io::Result<TcpListener> {
let listener = sys::tcp::listen(self.sys, backlog)?;
mem::forget(self);
Ok(TcpListener::from_std(listener))
}
pub fn set_reuseaddr(&self, reuseaddr: bool) -> io::Result<()> {
sys::tcp::set_reuseaddr(self.sys, reuseaddr)
}
}
impl Drop for TcpSocket {
fn drop(&mut self) {
sys::tcp::close(self.sys);
}
}
#[cfg(unix)]
impl AsRawFd for TcpSocket {
fn as_raw_fd(&self) -> RawFd {
self.sys
}
}
#[cfg(unix)]
impl FromRawFd for TcpSocket {
unsafe fn from_raw_fd(fd: RawFd) -> TcpSocket {
TcpSocket { sys: fd }
}
}
#[cfg(windows)]
impl IntoRawSocket for TcpSocket {
fn into_raw_socket(self) -> RawSocket {
let ret = self.sys as RawSocket;
mem::forget(self);
ret
}
}
#[cfg(windows)]
impl AsRawSocket for TcpSocket {
fn as_raw_socket(&self) -> RawSocket {
self.sys as RawSocket
}
}
#[cfg(windows)]
impl FromRawSocket for TcpSocket {
unsafe fn from_raw_socket(socket: RawSocket) -> TcpSocket {
TcpSocket { sys: socket as sys::tcp::TcpSocket }
}
}