@@ -33,7 +33,7 @@ impl<St: Stream> Peekable<St> {
3333
3434 delegate_access_inner ! ( stream, St , ( . ) ) ;
3535
36- /// Produces a `Peek` future which retrieves a reference to the next item
36+ /// Produces a future which retrieves a reference to the next item
3737 /// in the stream, or `None` if the underlying stream terminates.
3838 pub fn peek ( self : Pin < & mut Self > ) -> Peek < ' _ , St > {
3939 Peek { inner : Some ( self ) }
@@ -57,6 +57,54 @@ impl<St: Stream> Peekable<St> {
5757 } )
5858 }
5959
60+ /// Produces a future which retrieves a mutable reference to the next item
61+ /// in the stream, or `None` if the underlying stream terminates.
62+ ///
63+ /// # Examples
64+ ///
65+ /// ```
66+ /// # futures::executor::block_on(async {
67+ /// use futures::stream::{self, StreamExt};
68+ /// use futures::pin_mut;
69+ ///
70+ /// let stream = stream::iter(vec![1, 2, 3]).peekable();
71+ /// pin_mut!(stream);
72+ ///
73+ /// assert_eq!(stream.as_mut().peek_mut().await, Some(&mut 1));
74+ /// assert_eq!(stream.as_mut().next().await, Some(1));
75+ ///
76+ /// // Peek into the stream and modify the value which will be returned next
77+ /// if let Some(p) = stream.as_mut().peek_mut().await {
78+ /// if *p == 2 {
79+ /// *p = 5;
80+ /// }
81+ /// }
82+ ///
83+ /// assert_eq!(stream.collect::<Vec<_>>().await, vec![5, 3]);
84+ /// # });
85+ /// ```
86+ pub fn peek_mut ( self : Pin < & mut Self > ) -> PeekMut < ' _ , St > {
87+ PeekMut { inner : Some ( self ) }
88+ }
89+
90+ /// Peek retrieves a mutable reference to the next item in the stream.
91+ pub fn poll_peek_mut (
92+ self : Pin < & mut Self > ,
93+ cx : & mut Context < ' _ > ,
94+ ) -> Poll < Option < & mut St :: Item > > {
95+ let mut this = self . project ( ) ;
96+
97+ Poll :: Ready ( loop {
98+ if this. peeked . is_some ( ) {
99+ break this. peeked . as_mut ( ) ;
100+ } else if let Some ( item) = ready ! ( this. stream. as_mut( ) . poll_next( cx) ) {
101+ * this. peeked = Some ( item) ;
102+ } else {
103+ break None ;
104+ }
105+ } )
106+ }
107+
60108 /// Creates a future which will consume and return the next value of this
61109 /// stream if a condition is true.
62110 ///
@@ -220,6 +268,48 @@ where
220268 }
221269}
222270
271+ pin_project ! {
272+ /// Future for the [`Peekable::peek_mut`](self::Peekable::peek_mut) method.
273+ #[ must_use = "futures do nothing unless polled" ]
274+ pub struct PeekMut <' a, St : Stream > {
275+ inner: Option <Pin <& ' a mut Peekable <St >>>,
276+ }
277+ }
278+
279+ impl < St > fmt:: Debug for PeekMut < ' _ , St >
280+ where
281+ St : Stream + fmt:: Debug ,
282+ St :: Item : fmt:: Debug ,
283+ {
284+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
285+ f. debug_struct ( "PeekMut" ) . field ( "inner" , & self . inner ) . finish ( )
286+ }
287+ }
288+
289+ impl < St : Stream > FusedFuture for PeekMut < ' _ , St > {
290+ fn is_terminated ( & self ) -> bool {
291+ self . inner . is_none ( )
292+ }
293+ }
294+
295+ impl < ' a , St > Future for PeekMut < ' a , St >
296+ where
297+ St : Stream ,
298+ {
299+ type Output = Option < & ' a mut St :: Item > ;
300+
301+ fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
302+ let inner = self . project ( ) . inner ;
303+ if let Some ( peekable) = inner {
304+ ready ! ( peekable. as_mut( ) . poll_peek_mut( cx) ) ;
305+
306+ inner. take ( ) . unwrap ( ) . poll_peek_mut ( cx)
307+ } else {
308+ panic ! ( "PeekMut polled after completion" )
309+ }
310+ }
311+ }
312+
223313pin_project ! {
224314 /// Future for the [`Peekable::next_if`](self::Peekable::next_if) method.
225315 #[ must_use = "futures do nothing unless polled" ]
0 commit comments