about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
authorpiegames <git@piegames.de>2021-08-25 20:22:19 +0200
committerpiegames <git@piegames.de>2021-08-26 23:42:04 +0200
commitced597edb7e154092efde9df975ee76f9642a200 (patch)
tree3b4d98b0cd4b81686ab21089ad48a951d6193f32 /library/std/src
parenta992a11913b39a258158646bb1e03528c5aa5060 (diff)
downloadrust-ced597edb7e154092efde9df975ee76f9642a200.tar.gz
rust-ced597edb7e154092efde9df975ee76f9642a200.zip
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.
Diffstat (limited to 'library/std/src')
-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 336891ec1eb..45f5f3dac85 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.
     ///
@@ -798,6 +810,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
@@ -935,6 +978,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