@@ -19,7 +19,9 @@ use axum::extract::{FromRequestParts, Query};
1919use axum_extra:: json;
2020use axum_extra:: response:: ErasedJson ;
2121use diesel:: prelude:: * ;
22- use diesel_async:: RunQueryDsl ;
22+ use diesel_async:: { AsyncPgConnection , RunQueryDsl } ;
23+ use futures_util:: FutureExt ;
24+ use futures_util:: future:: { BoxFuture , always_ready} ;
2325use std:: str:: FromStr ;
2426
2527#[ derive( Debug , Deserialize , FromRequestParts , utoipa:: IntoParams ) ]
@@ -97,29 +99,25 @@ pub async fn find_crate(
9799 . optional ( ) ?
98100 . ok_or_else ( || crate_not_found ( & path. name ) ) ?;
99101
100- let mut versions_publishers_and_audit_actions = if include. versions {
101- let versions_and_publishers: Vec < ( Version , Option < User > ) > = Version :: belonging_to ( & krate)
102- . left_outer_join ( users:: table)
103- . select ( <( Version , Option < User > ) >:: as_select ( ) )
104- . order_by ( versions:: id. desc ( ) )
105- . load ( & mut conn)
106- . await ?;
107-
108- let versions = versions_and_publishers
109- . iter ( )
110- . map ( |( v, _) | v)
111- . collect :: < Vec < _ > > ( ) ;
112- let actions = VersionOwnerAction :: for_versions ( & mut conn, & versions) . await ?;
113- Some (
114- versions_and_publishers
115- . into_iter ( )
116- . zip ( actions)
117- . map ( |( ( v, pb) , aas) | ( v, pb, aas) )
118- . collect :: < Vec < _ > > ( ) ,
119- )
120- } else {
121- None
122- } ;
102+ let versions_and_publishers =
103+ load_versions_and_publishers ( & mut conn, & krate, include. versions ) . await ?;
104+ let mut versions_publishers_and_audit_actions =
105+ if let Some ( versions_and_publishers) = versions_and_publishers {
106+ let versions = versions_and_publishers
107+ . iter ( )
108+ . map ( |( v, _) | v)
109+ . collect :: < Vec < _ > > ( ) ;
110+ let actions = VersionOwnerAction :: for_versions ( & mut conn, & versions) . await ?;
111+ Some (
112+ versions_and_publishers
113+ . into_iter ( )
114+ . zip ( actions)
115+ . map ( |( ( v, pb) , aas) | ( v, pb, aas) )
116+ . collect :: < Vec < _ > > ( ) ,
117+ )
118+ } else {
119+ None
120+ } ;
123121 let ids = versions_publishers_and_audit_actions
124122 . as_ref ( )
125123 . map ( |vps| vps. iter ( ) . map ( |v| v. 0 . id ) . collect ( ) ) ;
@@ -226,6 +224,26 @@ pub async fn find_crate(
226224 } ) )
227225}
228226
227+ type VersionsAndPublishers = ( Version , Option < User > ) ;
228+
229+ fn load_versions_and_publishers < ' a > (
230+ conn : & mut AsyncPgConnection ,
231+ krate : & ' a Crate ,
232+ includes : bool ,
233+ ) -> BoxFuture < ' a , AppResult < Option < Vec < VersionsAndPublishers > > > > {
234+ if !includes {
235+ return always_ready ( || Ok ( None ) ) . boxed ( ) ;
236+ }
237+
238+ let fut = Version :: belonging_to ( & krate)
239+ . left_outer_join ( users:: table)
240+ . select ( <( Version , Option < User > ) >:: as_select ( ) )
241+ . order_by ( versions:: id. desc ( ) )
242+ . load ( conn) ;
243+
244+ async move { Ok ( Some ( fut. await ?) ) } . boxed ( )
245+ }
246+
229247#[ derive( Debug ) ]
230248struct ShowIncludeMode {
231249 versions : bool ,
0 commit comments