@@ -256,6 +256,12 @@ mod catch_unwind;
256256#[ allow( unreachable_pub) ] // https://github.com/rust-lang/rust/issues/57411
257257pub use self :: catch_unwind:: CatchUnwind ;
258258
259+ #[ cfg( feature = "std" ) ]
260+ mod shared;
261+ #[ cfg( feature = "std" ) ]
262+ #[ allow( unreachable_pub) ] // https://github.com/rust-lang/rust/issues/57411
263+ pub use self :: shared:: Shared ;
264+
259265impl < T : ?Sized > StreamExt for T where T : Stream { }
260266
261267/// An extension trait for `Stream`s that provides a variety of convenient
@@ -1501,6 +1507,72 @@ pub trait StreamExt: Stream {
15011507 assert_stream :: < Self :: Item , _ > ( Box :: pin ( self ) )
15021508 }
15031509
1510+ /// Create a cloneable handle to this stream where all handles will resolve
1511+ /// to the same result.
1512+ ///
1513+ /// The shared() method provides a method to convert any stream into a
1514+ /// cloneable stream. It enables a stream to be polled by multiple threads.
1515+ ///
1516+ /// This method is only available when the `std` feature of this library is
1517+ /// activiated, and it is activated by default.
1518+ ///
1519+ /// # Panics
1520+ /// If the capacity is zero. It must have space for at least one item.
1521+ ///
1522+ /// # Examples
1523+ ///
1524+ /// ```
1525+ /// use futures::executor::block_on;
1526+ /// use futures::stream::{self, StreamExt};
1527+ ///
1528+ /// let stream = stream::iter(1..=3);
1529+ /// let shared1 = stream.shared(4);
1530+ /// let shared2 = shared1.clone();
1531+ ///
1532+ /// assert_eq!(vec![1,2,3], block_on(shared1.collect::<Vec<_>>()));
1533+ /// assert_eq!(vec![1,2,3], block_on(shared2.collect::<Vec<_>>()));
1534+ /// ```
1535+ ///
1536+ /// ```
1537+ /// use futures::executor::block_on;
1538+ /// use futures::stream::{self, StreamExt};
1539+ /// use std::thread;
1540+ ///
1541+ /// let stream = stream::iter(1..=3);
1542+ /// let shared1 = stream.shared(4);
1543+ /// let shared2 = shared1.clone();
1544+ /// let join_handle = thread::spawn(move || {
1545+ /// assert_eq!(vec![1,2,3], block_on(shared2.collect::<Vec<_>>()));
1546+ /// });
1547+ /// assert_eq!(vec![1,2,3], block_on(shared1.collect::<Vec<_>>()));
1548+ /// join_handle.join().unwrap();
1549+ /// ```
1550+ ///
1551+ /// ```
1552+ /// # futures::executor::block_on(async {
1553+ /// use futures::stream::{self, StreamExt};
1554+ ///
1555+ /// let stream = stream::iter(vec![1,2,3]);
1556+ /// let mut shared1 = stream.shared(4);
1557+ ///
1558+ /// assert_eq!(Some(1), shared1.next().await);
1559+ ///
1560+ /// let mut shared2 = shared1.clone();
1561+ /// assert_eq!(Some(2), shared2.next().await);
1562+ /// assert_eq!(Some(3), shared2.next().await);
1563+ /// assert_eq!(vec![2,3], shared1.collect::<Vec<_>>().await);
1564+ /// assert_eq!(None, shared2.next().await);
1565+ /// # });
1566+ /// ```
1567+ #[ cfg( feature = "std" ) ]
1568+ fn shared ( self , capacity : usize ) -> Shared < Self >
1569+ where
1570+ Self : Sized ,
1571+ Self :: Item : Clone ,
1572+ {
1573+ Shared :: new ( self , capacity)
1574+ }
1575+
15041576 /// An adaptor for creating a buffered list of pending futures.
15051577 ///
15061578 /// If this stream's item can be converted into a future, then this adaptor
0 commit comments