Skip to content

Commit

Permalink
Add TcpListener::into_incoming and IntoIncoming
Browse files Browse the repository at this point in the history
The `incoming` method is really useful, however for some use cases the borrow
this introduces is needlessly restricting. Thus, an owned variant is added.
  • Loading branch information
piegamesde committed Aug 26, 2021
1 parent a992a11 commit ced597e
Showing 1 changed file with 51 additions and 0 deletions.
51 changes: 51 additions & 0 deletions library/std/src/net/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit ced597e

Please sign in to comment.