async_tcp/lib.rs
1/**************************************************************************************************
2 * *
3 * This Source Code Form is subject to the terms of the Mozilla Public *
4 * License, v. 2.0. If a copy of the MPL was not distributed with this *
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. *
6 * *
7 **************************************************************************************************/
8
9// ======================================== Documentation ======================================= \\
10
11//! This crate provides [`TcpListener`] and [`TcpStream`], two traits that can be implemented by
12//! any async versions of [`std::net::TcpListener`] and [`std::net::TcpStream`].
13
14// =========================================== Imports ========================================== \\
15
16#[cfg(feature = "async-io")]
17mod async_io;
18
19#[cfg(feature = "async-net")]
20mod async_net;
21
22use async_peek::AsyncPeek;
23use core::future::Future;
24use core::pin::Pin;
25use core::task::{Context, Poll};
26use futures_lite::{ready, AsyncRead, AsyncWrite, Stream};
27use std::io::Result;
28use std::net::{Shutdown, SocketAddr};
29
30// ========================================= Interfaces ========================================= \\
31
32/// A TCP socket server, listening for connections.
33///
34/// After creating a `TcpListener` by [`bind`ing] it to a socket address, it listens for incoming
35/// TCP connections. Thse can be accepted by calling [`accept()`] or by awaiting items from the
36/// stream of [`incoming`] connections.
37///
38/// The socket will be closed when all handles to it are dropped.
39///
40/// The Transmission Control Protocol is specified in [IETF RFC 793].
41///
42/// [`bind`ing]: TcpListener::bind()
43/// [`accept()`]: TcpListener::accept()
44/// [`incoming`]: TcpListener::incoming()
45/// [IETF RFC 793]: https://tools.ietf.org/html/rfc793
46pub trait TcpListener: Sized {
47 /// The type of a TCP connection created by [`accept`ing] an incoming connection.
48 ///
49 /// [`accept`ing]: TcpListener::accept()
50 type Stream: TcpStream;
51
52 /// Creates a new `TcpListener` bound to the given address.
53 ///
54 /// Binding with a port number of `0` will request that the operating system assigns an
55 /// available port to this listener. The assigned port can be queried via [`local_addr()`].
56 ///
57 /// ## Examples
58 ///
59 /// ```rust
60 /// # use async_net_ as async_net;
61 /// use async_tcp::TcpListener;
62 /// use std::net::SocketAddr;
63 /// # use std::io::Result;
64 /// use std::str::FromStr;
65 ///
66 /// # async fn tcp_bind() -> Result<impl TcpListener> {
67 /// #
68 /// let addr = SocketAddr::from_str("127.0.0.1:0").unwrap();
69 /// let listener = async_net::TcpListener::bind(addr).await?;
70 /// #
71 /// # Ok(listener) }
72 /// #
73 /// # smol::block_on(tcp_bind()).unwrap();
74 /// ```
75 ///
76 /// [`local_addr()`]: TcpListener::local_addr()
77 fn bind(addr: SocketAddr) -> Bind<Self>;
78
79 /// Returns the local socket address of this listener.
80 ///
81 /// ## Examples
82 ///
83 /// ```rust
84 /// # smol::block_on(async {
85 /// #
86 /// # use async_net_ as async_net;
87 /// use async_tcp::TcpListener;
88 /// use std::net::SocketAddr;
89 /// # use std::io::Result;
90 /// use std::str::FromStr;
91 ///
92 /// let addr = SocketAddr::from_str("127.0.0.1:1105").unwrap();
93 /// let listener = async_net::TcpListener::bind(addr).await?;
94 ///
95 /// # fn tcp_local_addr<Listener: TcpListener>(addr: SocketAddr, listener: Listener) -> Result<()> {
96 /// #
97 /// assert_eq!(addr, listener.local_addr()?);
98 /// #
99 /// # Ok(()) }
100 /// #
101 /// # tcp_local_addr(addr, listener)?;
102 /// #
103 /// # Result::<()>::Ok(()) }).unwrap();
104 /// ```
105 fn local_addr(&self) -> Result<SocketAddr>;
106
107 /// Accepts a new incoming connection.
108 ///
109 /// Returns a [`TcpStream`] and the address it is connected to.
110 ///
111 /// ## Examples
112 ///
113 /// ```rust
114 /// # smol::block_on(async {
115 /// #
116 /// # use async_net_ as async_net;
117 /// use async_tcp::{TcpListener, TcpStream};
118 /// use std::net::SocketAddr;
119 /// # use std::io::Result;
120 /// use std::str::FromStr;
121 ///
122 /// let addr = SocketAddr::from_str("127.0.0.1:0").unwrap();
123 /// let listener = async_net::TcpListener::bind(addr).await?;
124 ///
125 /// # let addr = listener.local_addr()?;
126 /// # let conn = smol::spawn(async_net::TcpStream::connect(addr));
127 /// #
128 /// # async fn tcp_accept<Listener: TcpListener>(
129 /// # listener: &Listener,
130 /// # ) -> Result<impl TcpStream> {
131 /// #
132 /// let (stream, addr) = listener.accept().await?;
133 /// assert_eq!(stream.peer_addr()?, addr);
134 /// #
135 /// # Ok(stream) }
136 /// #
137 /// # let stream = tcp_accept(&listener).await?;
138 /// # let conn = conn.await?;
139 /// # assert_eq!(conn.local_addr()?, stream.peer_addr()?);
140 /// # assert_eq!(conn.peer_addr()?, stream.local_addr()?);
141 /// #
142 /// # Result::<()>::Ok(()) }).unwrap();
143 /// ```
144 fn accept(&self) -> Accept<Self> {
145 Accept { listener: self }
146 }
147
148 /// Attempts to accept a new incoming connection from this listener.
149 ///
150 /// On success, returns a [`TcpStream`] and the address it is connected to.
151 ///
152 /// If no new incoming connection is ready to be accepted, the current task is registered to be
153 /// notified when one becomes ready to be accepted or the socket closed, and `Poll::Pending` is
154 /// returned.
155 ///
156 /// This method exists to be used by [`accept()`] and [`incoming()`], we recommend you use of
157 /// these methods instead.
158 ///
159 /// [`accept()`]: TcpListener::accept()
160 /// [`incoming()`]: TcpListener::incoming()
161 fn poll_accept(&self, ctx: &mut Context) -> Poll<Result<(Self::Stream, SocketAddr)>>;
162
163 /// Returns a stream of incoming connections.
164 ///
165 /// Iterating over this stream is equivalent to calling [`accept()`] in a loop. The stream of
166 /// connections is infinite, ie. it will never return `None`.
167 ///
168 /// ## Examples
169 ///
170 /// ```rust
171 /// # smol::block_on(async {
172 /// #
173 /// # use async_net_ as async_net;
174 /// use async_tcp::{TcpListener, TcpStream};
175 /// use futures_lite::StreamExt;
176 /// use std::net::SocketAddr;
177 /// # use std::io::Result;
178 /// use std::str::FromStr;
179 ///
180 /// let addr = SocketAddr::from_str("127.0.0.1:0").unwrap();
181 /// let listener = async_net::TcpListener::bind(addr).await?;
182 /// #
183 /// # let addr = listener.local_addr()?;
184 /// # let conn = smol::spawn(async_net::TcpStream::connect(addr));
185 /// #
186 /// # async fn tcp_incoming<Listener: TcpListener>(
187 /// # listener: &Listener,
188 /// # ) -> Result<impl TcpStream> {
189 /// #
190 /// let mut incoming = listener.incoming();
191 ///
192 /// while let Some(stream) = incoming.next().await {
193 /// let mut stream = stream?;
194 /// assert_eq!(stream.local_addr()?, listener.local_addr()?);
195 /// # return Ok(stream);
196 /// }
197 /// #
198 /// # unreachable!(); }
199 /// #
200 /// # let stream = tcp_incoming(&listener).await?;
201 /// # let conn = conn.await?;
202 /// # assert_eq!(conn.local_addr()?, stream.peer_addr()?);
203 /// # assert_eq!(conn.peer_addr()?, stream.local_addr()?);
204 /// #
205 /// # Result::<()>::Ok(()) }).unwrap();
206 /// ```
207 ///
208 /// [`accept()`]: TcpListener::accept()
209 fn incoming(&self) -> Incoming<Self> {
210 Incoming { listener: self }
211 }
212
213 /// Gets the value of the `IP_TTL` option on this socket.
214 ///
215 /// For more information about this option, see [`set_ttl()`].
216 ///
217 /// ## Examples
218 ///
219 /// ```rust
220 /// # smol::block_on(async {
221 /// #
222 /// # use async_net_ as async_net;
223 /// use async_tcp::TcpListener;
224 /// use std::net::SocketAddr;
225 /// # use std::io::Result;
226 /// use std::str::FromStr;
227 ///
228 /// let addr = SocketAddr::from_str("127.0.0.1:0").unwrap();
229 /// let listener = async_net::TcpListener::bind(addr).await.unwrap();
230 ///
231 /// # fn tcp_ttl<Listener: TcpListener>(listener: Listener) -> Result<()> {
232 /// #
233 /// listener.set_ttl(100)?;
234 /// assert_eq!(listener.ttl()?, 100);
235 /// #
236 /// # Ok(()) }
237 /// #
238 /// # tcp_ttl(listener)?;
239 /// #
240 /// # Result::<()>::Ok(()) }).unwrap();
241 /// ```
242 ///
243 /// [`set_ttl()`]: TcpListener::set_ttl()
244 fn ttl(&self) -> Result<u32>;
245
246 /// Sets the value for the `IP_TTL` option on this socket.
247 ///
248 /// This value sets the time-to-live field that is used in every packet sent from this socket.
249 ///
250 /// ## Example
251 ///
252 /// ```rust
253 /// # smol::block_on(async {
254 /// #
255 /// # use async_net_ as async_net;
256 /// use async_tcp::TcpListener;
257 /// use std::net::SocketAddr;
258 /// # use std::io::Result;
259 /// use std::str::FromStr;
260 ///
261 /// let addr = SocketAddr::from_str("127.0.0.1:0").unwrap();
262 /// let listener = async_net::TcpListener::bind(addr).await.unwrap();
263 ///
264 /// # fn tcp_set_ttl<Listener: TcpListener>(listener: Listener) -> Result<()> {
265 /// #
266 /// listener.set_ttl(100)?;
267 /// assert_eq!(listener.ttl()?, 100);
268 /// #
269 /// # Ok(()) }
270 /// #
271 /// # tcp_set_ttl(listener)?;
272 /// #
273 /// # Result::<()>::Ok(()) }).unwrap();
274 /// ```
275 fn set_ttl(&self, ttl: u32) -> Result<()>;
276}
277
278/// A TCP stream between a local and a remote socket.
279///
280/// A `TcpStream` can be created by either [`connect`ing] to an endpoint or [`accept`ing] a
281/// connection on a [`TcpListener`].
282///
283/// [`TcpStream`] is a bidirectional stream that implements [`AsyncPeek`], [`AsyncRead`] and
284/// [`AsyncWrite`].
285///
286/// The socket will be closed when all handles to it are dropped. The reading and writing portions
287/// of the connection can also be shut down individually with the [`shutdown()`] method.
288///
289/// [`connect`ing]: TcpStream::connect()
290/// [`accept`ing]: TcpListener::accept()
291/// [`shutdown()`]: TcpStream::shutdown()
292pub trait TcpStream: AsyncPeek + AsyncRead + AsyncWrite + Sized {
293 /// Opens a TCP connection to the specified address.
294 ///
295 /// ## Examples
296 ///
297 /// ```rust
298 /// # use async_net_ as async_net;
299 /// # use async_tcp::TcpListener;
300 /// use async_tcp::TcpStream;
301 /// use std::net::SocketAddr;
302 /// # use std::io::Result;
303 /// use std::str::FromStr;
304 ///
305 /// # async fn tcp_connect() -> Result<impl TcpStream> {
306 /// #
307 /// # let addr = SocketAddr::from_str("127.0.0.1:0").unwrap();
308 /// # let listener = async_net::TcpListener::bind(addr).await?;
309 /// # let addr = listener.local_addr()?;
310 /// // let addr = ...;
311 /// #
312 /// # let connect = smol::spawn(async move {
313 /// let stream = async_net::TcpStream::connect(addr).await?;
314 /// # Result::Ok(stream) });
315 /// #
316 /// # let (conn, peer_addr) = listener.accept().await?;
317 /// # let stream = connect.await?;
318 /// # assert_eq!(peer_addr, conn.peer_addr()?);
319 /// # assert_eq!(peer_addr, stream.local_addr()?);
320 /// assert_eq!(addr, stream.peer_addr()?);
321 /// #
322 /// # Ok(stream) }
323 /// #
324 /// # smol::block_on(tcp_connect()).unwrap();
325 /// ```
326 fn connect(addr: SocketAddr) -> Connect<Self>;
327
328 /// Returns the socket address of the local half of this TCP connection.
329 ///
330 /// ## Examples
331 ///
332 /// ```rust
333 /// # smol::block_on(async {
334 /// #
335 /// # use async_net_ as async_net;
336 /// # use async_tcp::TcpListener;
337 /// use async_tcp::TcpStream;
338 /// use std::net::{IpAddr, SocketAddr};
339 /// # use std::io::Result;
340 /// use std::str::FromStr;
341 ///
342 /// # let addr = SocketAddr::from_str("127.0.0.1:0").unwrap();
343 /// # let listener = async_net::TcpListener::bind(addr).await?;
344 /// # let addr = listener.local_addr()?;
345 /// // let addr = ...;
346 /// #
347 /// # let connect = smol::spawn(async move {
348 /// let stream = async_net::TcpStream::connect(addr).await?;
349 /// # Result::Ok(stream) });
350 /// #
351 /// # let (conn, peer_addr) = listener.accept().await?;
352 /// # let stream = connect.await?;
353 ///
354 /// # fn tcp_local_addr<Stream: TcpStream>(stream: Stream) -> Result<()> {
355 /// #
356 /// assert_eq!(stream.local_addr()?.ip(), IpAddr::from_str("127.0.0.1").unwrap());
357 /// #
358 /// # Ok(()) }
359 /// #
360 /// # tcp_local_addr(stream)?;
361 /// #
362 /// # Result::<()>::Ok(()) }).unwrap();
363 /// ```
364 fn local_addr(&self) -> Result<SocketAddr>;
365
366 /// Returns the socket address of the remote peer of this TCP connection.
367 ///
368 /// ## Examples
369 ///
370 /// ```rust
371 /// # smol::block_on(async {
372 /// #
373 /// # use async_net_ as async_net;
374 /// # use async_tcp::TcpListener;
375 /// use async_tcp::TcpStream;
376 /// use std::net::SocketAddr;
377 /// # use std::io::Result;
378 /// use std::str::FromStr;
379 ///
380 /// # let addr = SocketAddr::from_str("127.0.0.1:0").unwrap();
381 /// # let listener = async_net::TcpListener::bind(addr).await?;
382 /// # let addr = listener.local_addr()?;
383 /// // let addr = ...;
384 /// #
385 /// # let connect = smol::spawn(async move {
386 /// let stream = async_net::TcpStream::connect(addr).await?;
387 /// # Result::Ok(stream) });
388 /// #
389 /// # let (conn, peer_addr) = listener.accept().await?;
390 /// # let stream = connect.await?;
391 ///
392 /// # fn tcp_peer_addr<Stream: TcpStream>(addr: SocketAddr, stream: Stream) -> Result<()> {
393 /// #
394 /// assert_eq!(addr, stream.peer_addr()?);
395 /// #
396 /// # Ok(()) }
397 /// #
398 /// # tcp_peer_addr(addr, stream)?;
399 /// #
400 /// # Result::<()>::Ok(()) }).unwrap();
401 /// ```
402 fn peer_addr(&self) -> Result<SocketAddr>;
403
404 /// Shuts down the read half, write half, or both halves of this connection.
405 ///
406 /// This method will cause all pending and future I/O in the given directions to return
407 /// immediately with an appropriate value (see the documentation of [`Shutdown`]).
408 ///
409 /// ## Examples
410 ///
411 /// ```rust
412 /// # smol::block_on(async {
413 /// #
414 /// # use async_net_ as async_net;
415 /// # use async_tcp::TcpListener;
416 /// use async_tcp::TcpStream;
417 /// use std::net::{Shutdown, SocketAddr};
418 /// # use std::io::Result;
419 /// use std::str::FromStr;
420 ///
421 /// # let addr = SocketAddr::from_str("127.0.0.1:0").unwrap();
422 /// # let listener = async_net::TcpListener::bind(addr).await?;
423 /// # let addr = listener.local_addr()?;
424 /// // let addr = ...;
425 /// #
426 /// # let connect = smol::spawn(async move {
427 /// let stream = async_net::TcpStream::connect(addr).await?;
428 /// # Result::Ok(stream) });
429 /// #
430 /// # let (conn, peer_addr) = listener.accept().await?;
431 /// # let stream = connect.await?;
432 ///
433 /// # fn tcp_shutdown<Stream: TcpStream>(stream: Stream) -> Result<()> {
434 /// #
435 /// stream.shutdown(Shutdown::Both)?;
436 /// #
437 /// # Ok(()) }
438 /// #
439 /// # tcp_shutdown(stream)?;
440 /// #
441 /// # Result::<()>::Ok(()) }).unwrap();
442 /// ```
443 fn shutdown(&self, how: Shutdown) -> Result<()>;
444
445 /// Gets the value of the `TCP_NODELAY` option on this socket.
446 ///
447 /// For more information about this option, see [`set_nodelay()`].
448 ///
449 /// ## Examples
450 ///
451 /// ```rust
452 /// # smol::block_on(async {
453 /// #
454 /// # use async_net_ as async_net;
455 /// # use async_tcp::TcpListener;
456 /// use async_tcp::TcpStream;
457 /// use std::net::SocketAddr;
458 /// # use std::io::Result;
459 /// use std::str::FromStr;
460 ///
461 /// # let addr = SocketAddr::from_str("127.0.0.1:0").unwrap();
462 /// # let listener = async_net::TcpListener::bind(addr).await?;
463 /// # let addr = listener.local_addr()?;
464 /// // let addr = ...;
465 /// #
466 /// # let connect = smol::spawn(async move {
467 /// let stream = async_net::TcpStream::connect(addr).await?;
468 /// # Result::Ok(stream) });
469 /// #
470 /// # let (conn, peer_addr) = listener.accept().await?;
471 /// # let stream = connect.await?;
472 ///
473 /// # fn tcp_nodelay<Stream: TcpStream>(stream: Stream) -> Result<()> {
474 /// #
475 /// stream.set_nodelay(true)?;
476 /// assert_eq!(stream.nodelay()?, true);
477 /// #
478 /// # Ok(()) }
479 /// #
480 /// # tcp_nodelay(stream)?;
481 /// #
482 /// # Result::<()>::Ok(()) }).unwrap();
483 /// ```
484 ///
485 /// [`set_nodelay()`]: TcpStream::set_nodelay()
486 fn nodelay(&self) -> Result<bool>;
487
488 /// Sets the value of `TCP_NODELAY` option on this socket.
489 ///
490 /// If set, this option disables the Nagle algorithm. This means that segments are always sent
491 /// as soon as possible, even if there is only a small amount of data. When not set, data is
492 /// buffered until there is a sufficient amount to send out, thereby avoiding the frequent
493 /// reading of small packets.
494 ///
495 /// ## Examples
496 ///
497 /// ```rust
498 /// # smol::block_on(async {
499 /// #
500 /// # use async_net_ as async_net;
501 /// # use async_tcp::TcpListener;
502 /// use async_tcp::TcpStream;
503 /// use std::net::SocketAddr;
504 /// # use std::io::Result;
505 /// use std::str::FromStr;
506 ///
507 /// # let addr = SocketAddr::from_str("127.0.0.1:0").unwrap();
508 /// # let listener = async_net::TcpListener::bind(addr).await?;
509 /// # let addr = listener.local_addr()?;
510 /// // let addr = ...;
511 /// #
512 /// # let connect = smol::spawn(async move {
513 /// let stream = async_net::TcpStream::connect(addr).await?;
514 /// # Result::Ok(stream) });
515 /// #
516 /// # let (conn, peer_addr) = listener.accept().await?;
517 /// # let stream = connect.await?;
518 ///
519 /// # fn tcp_set_nodelay<Stream: TcpStream>(stream: Stream) -> Result<()> {
520 /// #
521 /// stream.set_nodelay(true)?;
522 /// assert_eq!(stream.nodelay()?, true);
523 /// #
524 /// # Ok(()) }
525 /// #
526 /// # tcp_set_nodelay(stream)?;
527 /// #
528 /// # Result::<()>::Ok(()) }).unwrap();
529 /// ```
530 fn set_nodelay(&self, nodelay: bool) -> Result<()>;
531
532 /// Gets the value of the `IP_TTL` option on this socket.
533 ///
534 /// For more information about this option, see [`set_ttl()`].
535 ///
536 /// ## Examples
537 ///
538 /// ```rust
539 /// # smol::block_on(async {
540 /// #
541 /// # use async_net_ as async_net;
542 /// # use async_tcp::TcpListener;
543 /// use async_tcp::TcpStream;
544 /// use std::net::SocketAddr;
545 /// # use std::io::Result;
546 /// use std::str::FromStr;
547 ///
548 /// # let addr = SocketAddr::from_str("127.0.0.1:0").unwrap();
549 /// # let listener = async_net::TcpListener::bind(addr).await?;
550 /// # let addr = listener.local_addr()?;
551 /// // let addr = ...;
552 /// #
553 /// # let connect = smol::spawn(async move {
554 /// let stream = async_net::TcpStream::connect(addr).await?;
555 /// # Result::Ok(stream) });
556 /// #
557 /// # let (conn, peer_addr) = listener.accept().await?;
558 /// # let stream = connect.await?;
559 ///
560 /// # fn tcp_ttl<Stream: TcpStream>(stream: Stream) -> Result<()> {
561 /// #
562 /// stream.set_ttl(100)?;
563 /// assert_eq!(stream.ttl()?, 100);
564 /// #
565 /// # Ok(()) }
566 /// #
567 /// # tcp_ttl(stream)?;
568 /// #
569 /// # Result::<()>::Ok(()) }).unwrap();
570 /// ```
571 ///
572 /// [`set_ttl()`]: TcpStream::set_ttl()
573 fn ttl(&self) -> Result<u32>;
574
575 /// Sets the value for the `IP_TTL` option on this socket.
576 ///
577 /// This value sets the time-to-live field that is used in every packet sent from this socket.
578 ///
579 /// ## Examples
580 ///
581 /// ```rust
582 /// # smol::block_on(async {
583 /// #
584 /// # use async_net_ as async_net;
585 /// # use async_tcp::TcpListener;
586 /// use async_tcp::TcpStream;
587 /// use std::net::SocketAddr;
588 /// # use std::io::Result;
589 /// use std::str::FromStr;
590 ///
591 /// # let addr = SocketAddr::from_str("127.0.0.1:0").unwrap();
592 /// # let listener = async_net::TcpListener::bind(addr).await?;
593 /// # let addr = listener.local_addr()?;
594 /// // let addr = ...;
595 /// #
596 /// # let connect = smol::spawn(async move {
597 /// let stream = async_net::TcpStream::connect(addr).await?;
598 /// # Result::Ok(stream) });
599 /// #
600 /// # let (conn, peer_addr) = listener.accept().await?;
601 /// # let stream = connect.await?;
602 ///
603 /// # fn tcp_set_ttl<Stream: TcpStream>(stream: Stream) -> Result<()> {
604 /// #
605 /// stream.set_ttl(100)?;
606 /// assert_eq!(stream.ttl()?, 100);
607 /// #
608 /// # Ok(()) }
609 /// #
610 /// # tcp_set_ttl(stream)?;
611 /// #
612 /// # Result::<()>::Ok(()) }).unwrap();
613 /// ```
614 fn set_ttl(&self, ttl: u32) -> Result<()>;
615}
616
617// ============================================ Types =========================================== \\
618
619/// Future returned by the [`TcpListener::bind()`] method.
620///
621/// If you are implementing [`TcpListener`] manually, you can construct a new instance of `Bind`
622/// using its implementation of `From<Pin<Box<dyn Future<Output = Result<Listener>> + Send>>>`.
623pub struct Bind<Listener> {
624 fut: Pin<Box<dyn Future<Output = Result<Listener>> + Send>>,
625}
626
627/// Future returned by the [`TcpListener::accept()`] method.
628pub struct Accept<'listener, Listener> {
629 listener: &'listener Listener,
630}
631
632/// Stream returned by the [`TcpListener::incoming()`] method.
633pub struct Incoming<'listener, Listener> {
634 listener: &'listener Listener,
635}
636
637/// Future returned by the [`TcpStream::connect()`] method.
638///
639/// If you are implementing [`TcpStream`] manually, you can construct a new instance of `Connect`
640/// using its implementation of `From<Pin<Box<dyn Future<Output = Result<Stream>> + Send>>>`.
641pub struct Connect<Stream> {
642 fut: Pin<Box<dyn Future<Output = Result<Stream>> + Send>>
643}
644
645// ========================================== impl From ========================================= \\
646
647impl<Listener> From<Pin<Box<dyn Future<Output = Result<Listener>> + Send>>> for Bind<Listener>
648where
649 Listener: TcpListener,
650{
651 fn from(fut: Pin<Box<dyn Future<Output = Result<Listener>> + Send>>) -> Self {
652 Bind { fut }
653 }
654}
655
656impl<Stream> From<Pin<Box<dyn Future<Output = Result<Stream>> + Send>>> for Connect<Stream>
657where
658 Stream: TcpStream,
659{
660 fn from(fut: Pin<Box<dyn Future<Output = Result<Stream>> + Send>>) -> Self {
661 Connect { fut }
662 }
663}
664
665// ========================================= impl Future ======================================== \\
666
667impl<Listener: TcpListener> Future for Bind<Listener> {
668 type Output = Result<Listener>;
669
670 fn poll(mut self: Pin<&mut Self>, ctx: &mut Context) -> Poll<Self::Output> {
671 self.fut.as_mut().poll(ctx)
672 }
673}
674
675impl<Listener: TcpListener> Future for Accept<'_, Listener> {
676 type Output = Result<(Listener::Stream, SocketAddr)>;
677
678 fn poll(self: Pin<&mut Self>, ctx: &mut Context) -> Poll<Self::Output> {
679 self.listener.poll_accept(ctx)
680 }
681}
682
683impl<Stream: TcpStream> Future for Connect<Stream> {
684 type Output = Result<Stream>;
685
686 fn poll(mut self: Pin<&mut Self>, ctx: &mut Context) -> Poll<Self::Output> {
687 self.fut.as_mut().poll(ctx)
688 }
689}
690
691// ========================================= impl Stream ======================================== \\
692
693impl<Listener: TcpListener> Stream for Incoming<'_, Listener> {
694 type Item = Result<Listener::Stream>;
695
696 fn poll_next(self: Pin<&mut Self>, ctx: &mut Context) -> Poll<Option<Self::Item>> {
697 let (stream, _) = ready!(self.listener.poll_accept(ctx))?;
698 Poll::Ready(Some(Ok(stream)))
699 }
700}