use std::{
io,
net::{SocketAddr, ToSocketAddrs},
};
use crate::{
api::{
self,
io::Io,
ops::{self, Recv, Shutdown},
resource::{AsResource, FromResource, IntoResource, Resource},
},
net::ops::TcpAccept,
};
use super::socket::Socket;
pub struct TcpListener(Socket);
impl IntoResource for TcpListener {
fn into_resource(self) -> Resource {
self.0.into_resource()
}
}
impl FromResource for TcpListener {
fn from_resource(resource: Resource) -> Self {
Self(Socket::from_resource(resource))
}
}
impl TcpListener {
pub async fn bind_async(addr: impl ToSocketAddrs) -> io::Result<Self> {
let mut addrs = addr.to_socket_addrs()?;
let socket = Socket::new(libc::AF_INET, libc::SOCK_STREAM, 0).await?;
let addr = addrs.next().unwrap();
socket.bind(addr).await?;
socket.listen().await?;
Ok(TcpListener(socket))
}
#[allow(deprecated)]
pub fn bind_sync(addr: impl ToSocketAddrs) -> io::Result<Self> {
let mut addrs = addr.to_socket_addrs()?;
let socket = Socket::new(libc::AF_INET, libc::SOCK_STREAM, 0).wait()?;
let addr = addrs.next().unwrap();
socket.bind(addr).wait()?;
socket.listen().wait()?;
Ok(TcpListener(socket))
}
pub fn accept(&self) -> Io<TcpAccept> {
let socket_accept_op = TcpAccept::new(self.0.as_resource().clone());
Io::from_op(socket_accept_op)
}
pub fn local_addr(&self) -> io::Result<SocketAddr> {
self.0.local_addr()
}
}
pub struct TcpSocket(Socket);
impl IntoResource for TcpSocket {
fn into_resource(self) -> Resource {
self.0.into_resource()
}
}
impl AsResource for TcpSocket {
fn as_resource(&self) -> &Resource {
self.0.as_resource()
}
}
impl FromResource for TcpSocket {
fn from_resource(resource: Resource) -> Self {
Self(Socket::from_resource(resource))
}
}
impl TcpSocket {
pub async fn connect_async(addr: SocketAddr) -> io::Result<Self> {
let socket = Socket::new(libc::AF_INET, libc::SOCK_STREAM, 0).await?;
api::connect(&socket, addr).await?;
Ok(TcpSocket(socket))
}
#[allow(deprecated)]
pub fn connect_sync(addr: SocketAddr) -> io::Result<Self> {
let socket = Socket::new(libc::AF_INET, libc::SOCK_STREAM, 0).wait()?;
api::connect(&socket, addr).wait()?;
Ok(TcpSocket(socket))
}
pub fn recv(&self, vec: Vec<u8>) -> Io<Recv<Vec<u8>>> {
self.0.recv(vec)
}
pub fn send(&self, vec: Vec<u8>) -> Io<ops::Send<Vec<u8>>> {
self.0.send(vec)
}
pub fn shutdown(&self, how: i32) -> Io<Shutdown> {
self.0.shutdown(how)
}
}