cap_async_std/net/
tcp_stream.rs

1use crate::net::{Shutdown, SocketAddr};
2use async_std::io::{self, IoSlice, IoSliceMut, Read, Write};
3use async_std::net;
4#[cfg(unix)]
5use async_std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
6use async_std::task::{Context, Poll};
7#[cfg(not(windows))]
8use io_lifetimes::{AsFd, BorrowedFd, OwnedFd};
9#[cfg(windows)]
10use io_lifetimes::{AsSocket, BorrowedSocket, OwnedSocket};
11use std::fmt;
12use std::pin::Pin;
13#[cfg(windows)]
14use {
15    async_std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket},
16    io_extras::os::windows::{
17        AsHandleOrSocket, AsRawHandleOrSocket, BorrowedHandleOrSocket, IntoRawHandleOrSocket,
18        OwnedHandleOrSocket, RawHandleOrSocket,
19    },
20};
21
22/// A TCP stream between a local and a remote socket.
23///
24/// This corresponds to [`async_std::net::TcpStream`].
25///
26/// This `TcpStream` has no `connect` method. To create a `TcpStream`, first
27/// obtain a [`Pool`] permitting the address, and then call
28/// [`Pool::connect_tcp_stream`].
29///
30/// [`Pool`]: struct.Pool.html
31/// [`Pool::connect_tcp_stream`]: struct.Pool.html#method.connect_tcp_stream
32#[derive(Clone)]
33pub struct TcpStream {
34    std: net::TcpStream,
35}
36
37impl TcpStream {
38    /// Constructs a new instance of `Self` from the given
39    /// `async_std::net::TcpStream`.
40    ///
41    /// This grants access the resources the `async_std::net::TcpStream`
42    /// instance already has access to.
43    #[inline]
44    pub fn from_std(std: net::TcpStream) -> Self {
45        Self { std }
46    }
47
48    /// Returns the remote address that this stream is connected to.
49    ///
50    /// This corresponds to [`async_std::net::TcpStream::peer_addr`].
51    #[inline]
52    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
53        self.std.peer_addr()
54    }
55
56    /// Returns the local socket address of this listener.
57    ///
58    /// This corresponds to [`async_std::net::TcpStream::local_addr`].
59    #[inline]
60    pub fn local_addr(&self) -> io::Result<SocketAddr> {
61        self.std.local_addr()
62    }
63
64    /// Shuts down the read, write, or both halves of this connection.
65    ///
66    /// This corresponds to [`async_std::net::TcpStream::shutdown`].
67    #[inline]
68    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
69        self.std.shutdown(how)
70    }
71
72    // async_std doesn't have `try_clone`.
73
74    // async_std doesn't have `set_read_timeout`.
75
76    // async_std doesn't have `set_write_timeout`.
77
78    // async_std doesn't have `read_timeout`.
79
80    // async_std doesn't have `write_timeout`.
81
82    /// Receives data on the socket from the remote address to which it is
83    /// connected, without removing that data from the queue.
84    ///
85    /// This corresponds to [`async_std::net::TcpStream::peek`].
86    #[inline]
87    pub async fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
88        self.std.peek(buf).await
89    }
90
91    /// Sets the value of the `TCP_NODELAY` option on this socket.
92    ///
93    /// This corresponds to [`async_std::net::TcpStream::set_nodelay`].
94    #[inline]
95    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
96        self.std.set_nodelay(nodelay)
97    }
98
99    /// Gets the value of the `TCP_NODELAY` option on this socket.
100    ///
101    /// This corresponds to [`async_std::net::TcpStream::nodelay`].
102    #[inline]
103    pub fn nodelay(&self) -> io::Result<bool> {
104        self.std.nodelay()
105    }
106
107    /// Sets the value for the `IP_TTL` option on this socket.
108    ///
109    /// This corresponds to [`async_std::net::TcpStream::set_ttl`].
110    #[inline]
111    pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
112        self.std.set_ttl(ttl)
113    }
114
115    /// Gets the value of the `IP_TTL` option for this socket.
116    ///
117    /// This corresponds to [`async_std::net::TcpStream::ttl`].
118    #[inline]
119    pub fn ttl(&self) -> io::Result<u32> {
120        self.std.ttl()
121    }
122
123    // async_std doesn't have `take_error`.
124
125    // async_std doesn't have `set_nonblocking`.
126}
127
128// Safety: `SocketlikeViewType` is implemented for `std`'s socket types.
129unsafe impl io_lifetimes::views::SocketlikeViewType for TcpStream {}
130
131#[cfg(not(windows))]
132impl FromRawFd for TcpStream {
133    #[inline]
134    unsafe fn from_raw_fd(fd: RawFd) -> Self {
135        Self::from_std(net::TcpStream::from_raw_fd(fd))
136    }
137}
138
139#[cfg(not(windows))]
140impl From<OwnedFd> for TcpStream {
141    #[inline]
142    fn from(fd: OwnedFd) -> Self {
143        Self::from_std(net::TcpStream::from(fd))
144    }
145}
146
147#[cfg(windows)]
148impl FromRawSocket for TcpStream {
149    #[inline]
150    unsafe fn from_raw_socket(socket: RawSocket) -> Self {
151        Self::from_std(net::TcpStream::from_raw_socket(socket))
152    }
153}
154
155#[cfg(windows)]
156impl From<OwnedSocket> for TcpStream {
157    #[inline]
158    fn from(socket: OwnedSocket) -> Self {
159        Self::from_std(net::TcpStream::from(socket))
160    }
161}
162
163#[cfg(not(windows))]
164impl AsRawFd for TcpStream {
165    #[inline]
166    fn as_raw_fd(&self) -> RawFd {
167        self.std.as_raw_fd()
168    }
169}
170
171#[cfg(not(windows))]
172impl AsFd for TcpStream {
173    #[inline]
174    fn as_fd(&self) -> BorrowedFd<'_> {
175        self.std.as_fd()
176    }
177}
178
179#[cfg(windows)]
180impl AsRawSocket for TcpStream {
181    #[inline]
182    fn as_raw_socket(&self) -> RawSocket {
183        self.std.as_raw_socket()
184    }
185}
186
187#[cfg(windows)]
188impl AsSocket for TcpStream {
189    #[inline]
190    fn as_socket(&self) -> BorrowedSocket<'_> {
191        self.std.as_socket()
192    }
193}
194
195#[cfg(windows)]
196impl AsRawHandleOrSocket for TcpStream {
197    #[inline]
198    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
199        self.std.as_raw_handle_or_socket()
200    }
201}
202
203#[cfg(windows)]
204impl AsHandleOrSocket for TcpStream {
205    #[inline]
206    fn as_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
207        self.std.as_handle_or_socket()
208    }
209}
210
211#[cfg(not(windows))]
212impl IntoRawFd for TcpStream {
213    #[inline]
214    fn into_raw_fd(self) -> RawFd {
215        self.std.into_raw_fd()
216    }
217}
218
219#[cfg(not(windows))]
220impl From<TcpStream> for OwnedFd {
221    #[inline]
222    fn from(stream: TcpStream) -> OwnedFd {
223        stream.std.into()
224    }
225}
226
227#[cfg(windows)]
228impl IntoRawSocket for TcpStream {
229    #[inline]
230    fn into_raw_socket(self) -> RawSocket {
231        self.std.into_raw_socket()
232    }
233}
234
235#[cfg(windows)]
236impl From<TcpStream> for OwnedSocket {
237    #[inline]
238    fn from(stream: TcpStream) -> OwnedSocket {
239        stream.std.into()
240    }
241}
242
243#[cfg(windows)]
244impl IntoRawHandleOrSocket for TcpStream {
245    #[inline]
246    fn into_raw_handle_or_socket(self) -> RawHandleOrSocket {
247        self.std.into_raw_handle_or_socket()
248    }
249}
250
251#[cfg(windows)]
252impl From<TcpStream> for OwnedHandleOrSocket {
253    #[inline]
254    fn from(stream: TcpStream) -> Self {
255        stream.std.into()
256    }
257}
258
259impl Read for TcpStream {
260    #[inline]
261    fn poll_read(
262        mut self: Pin<&mut Self>,
263        cx: &mut Context,
264        buf: &mut [u8],
265    ) -> Poll<io::Result<usize>> {
266        Read::poll_read(Pin::new(&mut self.std), cx, buf)
267    }
268
269    #[inline]
270    fn poll_read_vectored(
271        mut self: Pin<&mut Self>,
272        cx: &mut Context,
273        bufs: &mut [IoSliceMut],
274    ) -> Poll<io::Result<usize>> {
275        Read::poll_read_vectored(Pin::new(&mut self.std), cx, bufs)
276    }
277
278    // async_std doesn't have `is_read_vectored`.
279
280    // async_std doesn't have `initializer`.
281}
282
283impl Read for &TcpStream {
284    #[inline]
285    fn poll_read(
286        self: Pin<&mut Self>,
287        cx: &mut Context,
288        buf: &mut [u8],
289    ) -> Poll<io::Result<usize>> {
290        Read::poll_read(Pin::new(&mut &self.std), cx, buf)
291    }
292
293    #[inline]
294    fn poll_read_vectored(
295        self: Pin<&mut Self>,
296        cx: &mut Context,
297        bufs: &mut [IoSliceMut],
298    ) -> Poll<io::Result<usize>> {
299        Read::poll_read_vectored(Pin::new(&mut &self.std), cx, bufs)
300    }
301
302    // async_std doesn't have `is_read_vectored`.
303
304    // async_std doesn't have `initializer`.
305}
306
307impl Write for TcpStream {
308    #[inline]
309    fn poll_write(
310        mut self: Pin<&mut Self>,
311        cx: &mut Context,
312        buf: &[u8],
313    ) -> Poll<io::Result<usize>> {
314        Write::poll_write(Pin::new(&mut self.std), cx, buf)
315    }
316
317    #[inline]
318    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
319        Write::poll_flush(Pin::new(&mut self.std), cx)
320    }
321
322    #[inline]
323    fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
324        Write::poll_close(Pin::new(&mut self.std), cx)
325    }
326
327    #[inline]
328    fn poll_write_vectored(
329        mut self: Pin<&mut Self>,
330        cx: &mut Context,
331        bufs: &[IoSlice],
332    ) -> Poll<io::Result<usize>> {
333        Write::poll_write_vectored(Pin::new(&mut self.std), cx, bufs)
334    }
335
336    // async_std doesn't have `is_write_vectored`.
337
338    // async_std doesn't have `write_all_vectored`.
339}
340
341impl Write for &TcpStream {
342    #[inline]
343    fn poll_write(self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll<io::Result<usize>> {
344        Write::poll_write(Pin::new(&mut &self.std), cx, buf)
345    }
346
347    #[inline]
348    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
349        Write::poll_flush(Pin::new(&mut &self.std), cx)
350    }
351
352    #[inline]
353    fn poll_close(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
354        Write::poll_close(Pin::new(&mut &self.std), cx)
355    }
356
357    #[inline]
358    fn poll_write_vectored(
359        self: Pin<&mut Self>,
360        cx: &mut Context,
361        bufs: &[IoSlice],
362    ) -> Poll<io::Result<usize>> {
363        Write::poll_write_vectored(Pin::new(&mut &self.std), cx, bufs)
364    }
365
366    // async_std doesn't have `is_write_vectored`.
367
368    // async_std doesn't have `write_all_vectored`.
369}
370
371impl fmt::Debug for TcpStream {
372    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
373        self.std.fmt(f)
374    }
375}