@@ -99,13 +99,8 @@ pub async fn list_versions(
9999 None => None ,
100100 } ;
101101
102- // Sort by semver by default
103- let versions_and_publishers = match & params. sort . as_ref ( ) . map ( |s| s. to_lowercase ( ) ) . as_deref ( ) {
104- Some ( "date" ) => {
105- list_by_date ( crate_id, pagination. as_ref ( ) , & params, & req, & mut conn) . await ?
106- }
107- _ => list_by_semver ( crate_id, pagination. as_ref ( ) , & params, & req, & mut conn) . await ?,
108- } ;
102+ let versions_and_publishers =
103+ list ( crate_id, pagination. as_ref ( ) , & params, & req, & mut conn) . await ?;
109104
110105 let versions = versions_and_publishers
111106 . data
@@ -126,12 +121,12 @@ pub async fn list_versions(
126121 } ) )
127122}
128123
129- /// Seek-based pagination of versions by date
124+ /// Seek-based pagination of versions
130125///
131126/// # Panics
132127///
133- /// This function will panic if `option ` is built with `enable_pages` set to true.
134- async fn list_by_date (
128+ /// This function will panic if `options ` is built with `enable_pages` set to true.
129+ async fn list (
135130 crate_id : i32 ,
136131 options : Option < & PaginationOptions > ,
137132 params : & ListQueryParams ,
@@ -140,113 +135,11 @@ async fn list_by_date(
140135) -> AppResult < PaginatedVersionsAndPublishers > {
141136 use seek:: * ;
142137
143- let make_base_query = || {
144- let mut query = versions:: table
145- . filter ( versions:: crate_id. eq ( crate_id) )
146- . left_outer_join ( users:: table)
147- . select ( <( Version , Option < User > ) >:: as_select ( ) )
148- . into_boxed ( ) ;
149-
150- if !params. nums . is_empty ( ) {
151- query = query. filter ( versions:: num. eq_any ( params. nums . iter ( ) . map ( |s| s. as_str ( ) ) ) ) ;
152- }
153- query
138+ let seek = match & params. sort . as_ref ( ) . map ( |s| s. to_lowercase ( ) ) . as_deref ( ) {
139+ Some ( "date" ) => Seek :: Date ,
140+ _ => Seek :: Semver ,
154141 } ;
155142
156- let mut query = make_base_query ( ) ;
157-
158- if let Some ( options) = options {
159- assert ! (
160- !matches!( & options. page, Page :: Numeric ( _) ) ,
161- "?page= is not supported"
162- ) ;
163- if let Some ( SeekPayload :: Date ( Date { created_at, id } ) ) = Seek :: Date . after ( & options. page ) ? {
164- query = query. filter (
165- versions:: created_at
166- . eq ( created_at)
167- . and ( versions:: id. lt ( id) )
168- . or ( versions:: created_at. lt ( created_at) ) ,
169- )
170- }
171- query = query. limit ( options. per_page ) ;
172- }
173-
174- query = query. order ( ( versions:: created_at. desc ( ) , versions:: id. desc ( ) ) ) ;
175-
176- let data: Vec < ( Version , Option < User > ) > = query. load ( conn) . await ?;
177- let mut next_page = None ;
178- if let Some ( options) = options {
179- next_page = next_seek_params ( & data, options, |last| Seek :: Date . to_payload ( last) ) ?
180- . map ( |p| req. query_with_params ( p) ) ;
181- } ;
182-
183- let release_tracks = if params. include ( ) ?. release_tracks {
184- let mut sorted_versions = IndexSet :: new ( ) ;
185- if options. is_some ( ) {
186- versions:: table
187- . filter ( versions:: crate_id. eq ( crate_id) )
188- . filter ( not ( versions:: yanked) )
189- . select ( versions:: num)
190- . load_stream :: < String > ( conn)
191- . await ?
192- . try_for_each ( |num| {
193- if let Ok ( semver) = semver:: Version :: parse ( & num) {
194- sorted_versions. insert ( semver) ;
195- } ;
196- future:: ready ( Ok ( ( ) ) )
197- } )
198- . await ?;
199- } else {
200- sorted_versions = data
201- . iter ( )
202- . flat_map ( |( version, _) | {
203- ( !version. yanked )
204- . then_some ( version)
205- . and_then ( |v| semver:: Version :: parse ( & v. num ) . ok ( ) )
206- } )
207- . collect ( ) ;
208- }
209-
210- sorted_versions. sort_unstable_by ( |a, b| b. cmp ( a) ) ;
211- Some ( ReleaseTracks :: from_sorted_semver_iter (
212- sorted_versions. iter ( ) ,
213- ) )
214- } else {
215- None
216- } ;
217-
218- // Since the total count is retrieved through an additional query, to maintain consistency
219- // with other pagination methods, we only make a count query while data is not empty.
220- let total = if !data. is_empty ( ) {
221- make_base_query ( ) . count ( ) . get_result ( conn) . await ?
222- } else {
223- 0
224- } ;
225-
226- Ok ( PaginatedVersionsAndPublishers {
227- data,
228- meta : ResponseMeta {
229- total,
230- next_page,
231- release_tracks,
232- } ,
233- } )
234- }
235-
236- /// Seek-based pagination of versions by semver
237- ///
238- /// # Panics
239- ///
240- /// This function will panic if `option` is built with `enable_pages` set to true.
241- async fn list_by_semver (
242- crate_id : i32 ,
243- options : Option < & PaginationOptions > ,
244- params : & ListQueryParams ,
245- req : & Parts ,
246- conn : & mut AsyncPgConnection ,
247- ) -> AppResult < PaginatedVersionsAndPublishers > {
248- use seek:: * ;
249-
250143 let make_base_query = || {
251144 let mut query = versions:: table
252145 . filter ( versions:: crate_id. eq ( crate_id) )
@@ -267,23 +160,40 @@ async fn list_by_semver(
267160 !matches!( & options. page, Page :: Numeric ( _) ) ,
268161 "?page= is not supported"
269162 ) ;
270- if let Some ( SeekPayload :: Semver ( Semver { num, id } ) ) = Seek :: Semver . after ( & options. page ) ? {
271- query = query. filter (
272- versions:: semver_ord
273- . eq ( semver_ord ( num. clone ( ) ) )
274- . and ( versions:: id. lt ( id) )
275- . or ( versions:: semver_ord. lt ( semver_ord ( num) ) ) ,
276- )
163+
164+ match seek. after ( & options. page ) ? {
165+ Some ( SeekPayload :: Date ( Date { created_at, id } ) ) => {
166+ query = query. filter (
167+ versions:: created_at
168+ . eq ( created_at)
169+ . and ( versions:: id. lt ( id) )
170+ . or ( versions:: created_at. lt ( created_at) ) ,
171+ )
172+ }
173+ Some ( SeekPayload :: Semver ( Semver { num, id } ) ) => {
174+ query = query. filter (
175+ versions:: semver_ord
176+ . eq ( semver_ord ( num. clone ( ) ) )
177+ . and ( versions:: id. lt ( id) )
178+ . or ( versions:: semver_ord. lt ( semver_ord ( num) ) ) ,
179+ )
180+ }
181+ None => { }
277182 }
183+
278184 query = query. limit ( options. per_page ) ;
279185 }
280186
281- query = query. order ( ( versions:: semver_ord. desc ( ) , versions:: id. desc ( ) ) ) ;
187+ if seek == Seek :: Date {
188+ query = query. order ( ( versions:: created_at. desc ( ) , versions:: id. desc ( ) ) ) ;
189+ } else {
190+ query = query. order ( ( versions:: semver_ord. desc ( ) , versions:: id. desc ( ) ) ) ;
191+ }
282192
283193 let data: Vec < ( Version , Option < User > ) > = query. load ( conn) . await ?;
284194 let mut next_page = None ;
285195 if let Some ( options) = options {
286- next_page = next_seek_params ( & data, options, |last| Seek :: Semver . to_payload ( last) ) ?
196+ next_page = next_seek_params ( & data, options, |last| seek . to_payload ( last) ) ?
287197 . map ( |p| req. query_with_params ( p) ) ;
288198 } ;
289199
0 commit comments