use std::{
io,
net::SocketAddr,
os::unix::prelude::{AsRawFd, FromRawFd, RawFd},
};
use crate::{
buf::fixed::FixedBuf,
buf::{BoundedBuf, BoundedBufMut},
io::{SharedFd, Socket},
UnsubmittedWrite,
};
pub struct TcpStream {
pub(super) inner: Socket,
}
impl TcpStream {
pub async fn connect(addr: SocketAddr) -> io::Result<TcpStream> {
let socket = Socket::new(addr, libc::SOCK_STREAM)?;
socket.connect(socket2::SockAddr::from(addr)).await?;
let tcp_stream = TcpStream { inner: socket };
Ok(tcp_stream)
}
pub fn from_std(socket: std::net::TcpStream) -> Self {
let inner = Socket::from_std(socket);
Self { inner }
}
pub(crate) fn from_socket(inner: Socket) -> Self {
Self { inner }
}
pub async fn read<T: BoundedBufMut>(&self, buf: T) -> crate::BufResult<usize, T> {
self.inner.read(buf).await
}
pub async fn read_fixed<T>(&self, buf: T) -> crate::BufResult<usize, T>
where
T: BoundedBufMut<BufMut = FixedBuf>,
{
self.inner.read_fixed(buf).await
}
pub fn write<T: BoundedBuf>(&self, buf: T) -> UnsubmittedWrite<T> {
self.inner.write(buf)
}
pub async fn write_all<T: BoundedBuf>(&self, buf: T) -> crate::BufResult<(), T> {
self.inner.write_all(buf).await
}
pub async fn write_fixed<T>(&self, buf: T) -> crate::BufResult<usize, T>
where
T: BoundedBuf<Buf = FixedBuf>,
{
self.inner.write_fixed(buf).await
}
pub async fn write_fixed_all<T>(&self, buf: T) -> crate::BufResult<(), T>
where
T: BoundedBuf<Buf = FixedBuf>,
{
self.inner.write_fixed_all(buf).await
}
pub async fn writev<T: BoundedBuf>(&self, buf: Vec<T>) -> crate::BufResult<usize, Vec<T>> {
self.inner.writev(buf).await
}
pub fn shutdown(&self, how: std::net::Shutdown) -> io::Result<()> {
self.inner.shutdown(how)
}
pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
self.inner.set_nodelay(nodelay)
}
}
impl FromRawFd for TcpStream {
unsafe fn from_raw_fd(fd: RawFd) -> Self {
TcpStream::from_socket(Socket::from_shared_fd(SharedFd::new(fd)))
}
}
impl AsRawFd for TcpStream {
fn as_raw_fd(&self) -> RawFd {
self.inner.as_raw_fd()
}
}