@@ -4,6 +4,7 @@ use std::task::{Context, Poll};
44
55use diesel:: QueryResult ;
66use futures_core:: { TryFuture , TryStream } ;
7+ use futures_util:: stream:: TryCollect ;
78use futures_util:: { TryFutureExt , TryStreamExt } ;
89
910// We use a custom future implementation here to erase some lifetimes
@@ -84,29 +85,38 @@ where
8485/// Consumes the entire stream to ensure proper cleanup before returning which is
8586/// required to fix: https://github.com/weiznich/diesel_async/issues/269
8687#[ repr( transparent) ]
87- pub struct LoadNext < T : TryStreamExt > {
88- future : futures_util:: stream:: TryCollect < T , Vec < T :: Ok > > ,
88+ pub struct LoadNext < F , T >
89+ where
90+ F : TryStream < Ok = T , Error = diesel:: result:: Error > ,
91+ {
92+ future : TryCollect < F , Vec < T > > ,
8993}
9094
91- impl < T > LoadNext < T >
95+ impl < F , T > LoadNext < F , T >
9296where
93- T : TryStream < Error = diesel:: result:: Error > + Unpin ,
97+ F : TryStream < Ok = T , Error = diesel:: result:: Error > ,
9498{
95- pub ( crate ) fn new ( stream : T ) -> Self {
99+ pub ( crate ) fn new ( stream : F ) -> Self {
96100 Self {
97101 future : stream. try_collect ( ) ,
98102 }
99103 }
100104}
101105
102- impl < T > Future for LoadNext < T >
106+ impl < F , T > Future for LoadNext < F , T >
103107where
104- T : TryStream < Error = diesel:: result:: Error > + Unpin ,
108+ F : TryStream < Ok = T , Error = diesel:: result:: Error > ,
109+ TryCollect < F , Vec < T > > : Future < Output = Result < Vec < T > , diesel:: result:: Error > > ,
105110{
106- type Output = QueryResult < T :: Ok > ;
111+ type Output = QueryResult < T > ;
107112
108- fn poll ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
109- match Pin :: new ( & mut self . future ) . poll ( cx) {
113+ fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
114+ match unsafe {
115+ // SAFETY: This projects pinning to the only inner field
116+ self . map_unchecked_mut ( |s| & mut s. future )
117+ }
118+ . poll ( cx)
119+ {
110120 Poll :: Ready ( Ok ( results) ) => match results. into_iter ( ) . next ( ) {
111121 Some ( first) => Poll :: Ready ( Ok ( first) ) ,
112122 None => Poll :: Ready ( Err ( diesel:: result:: Error :: NotFound ) ) ,
0 commit comments