about summary refs log tree commit diff
path: root/library/std/src/net/tcp.rs
diff options
context:
space:
mode:
authorYuki Okushi <jtitor@2k36.org>2021-09-17 14:09:45 +0900
committerGitHub <noreply@github.com>2021-09-17 14:09:45 +0900
commit0f06e366035fef3034c82c5ae80f7ecabd8bafbd (patch)
tree7648de9271b1616db3cf077f08aa5c98f3df00f8 /library/std/src/net/tcp.rs
parent81dc21699e7376afcf7469104ad8acb7c5f09269 (diff)
parentced597edb7e154092efde9df975ee76f9642a200 (diff)
downloadrust-0f06e366035fef3034c82c5ae80f7ecabd8bafbd.tar.gz
rust-0f06e366035fef3034c82c5ae80f7ecabd8bafbd.zip
Rollup merge of #88339 - piegamesde:master, r=joshtriplett
Add TcpListener::into_incoming and IntoIncoming

The `incoming` method is really useful, however for some use cases the borrow
this introduces is needlessly restricting. Thus, an owned variant is added.

r? ``@joshtriplett``
Diffstat (limited to 'library/std/src/net/tcp.rs')
-rw-r--r--library/std/src/net/tcp.rs51
1 files changed, 51 insertions, 0 deletions
diff --git a/library/std/src/net/tcp.rs b/library/std/src/net/tcp.rs
index 5b4a9fa7979..223726d45d7 100644
--- a/library/std/src/net/tcp.rs
+++ b/library/std/src/net/tcp.rs
@@ -96,6 +96,18 @@ pub struct Incoming<'a> {
     listener: &'a TcpListener,
 }
 
+/// An iterator that infinitely [`accept`]s connections on a [`TcpListener`].
+///
+/// This `struct` is created by the [`TcpListener::into_incoming`] method.
+/// See its documentation for more.
+///
+/// [`accept`]: TcpListener::accept
+#[derive(Debug)]
+#[unstable(feature = "tcplistener_into_incoming", issue = "88339")]
+pub struct IntoIncoming {
+    listener: TcpListener,
+}
+
 impl TcpStream {
     /// Opens a TCP connection to a remote host.
     ///
@@ -845,6 +857,37 @@ impl TcpListener {
         Incoming { listener: self }
     }
 
+    /// Turn this into an iterator over the connections being received on this
+    /// listener.
+    ///
+    /// The returned iterator will never return [`None`] and will also not yield
+    /// the peer's [`SocketAddr`] structure. Iterating over it is equivalent to
+    /// calling [`TcpListener::accept`] in a loop.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(tcplistener_into_incoming)]
+    /// use std::net::{TcpListener, TcpStream};
+    ///
+    /// fn listen_on(port: u16) -> impl Iterator<Item = TcpStream> {
+    ///     let listener = TcpListener::bind("127.0.0.1:80").unwrap();
+    ///     listener.into_incoming()
+    ///         .filter_map(Result::ok) /* Ignore failed connections */
+    /// }
+    ///
+    /// fn main() -> std::io::Result<()> {
+    ///     for stream in listen_on(80) {
+    ///         /* handle the connection here */
+    ///     }
+    ///     Ok(())
+    /// }
+    /// ```
+    #[unstable(feature = "tcplistener_into_incoming", issue = "88339")]
+    pub fn into_incoming(self) -> IntoIncoming {
+        IntoIncoming { listener: self }
+    }
+
     /// Sets the value for the `IP_TTL` option on this socket.
     ///
     /// This value sets the time-to-live field that is used in every packet sent
@@ -982,6 +1025,14 @@ impl<'a> Iterator for Incoming<'a> {
     }
 }
 
+#[unstable(feature = "tcplistener_into_incoming", issue = "88339")]
+impl Iterator for IntoIncoming {
+    type Item = io::Result<TcpStream>;
+    fn next(&mut self) -> Option<io::Result<TcpStream>> {
+        Some(self.listener.accept().map(|p| p.0))
+    }
+}
+
 impl AsInner<net_imp::TcpListener> for TcpListener {
     fn as_inner(&self) -> &net_imp::TcpListener {
         &self.0