@@ -442,6 +442,8 @@ pub(crate) async fn crate_details_handler(
442
442
struct ReleaseList {
443
443
releases : Vec < Release > ,
444
444
crate_name : String ,
445
+ inner_path : String ,
446
+ target : String ,
445
447
}
446
448
447
449
impl_axum_webpage ! {
@@ -452,28 +454,74 @@ impl_axum_webpage! {
452
454
453
455
#[ tracing:: instrument]
454
456
pub ( crate ) async fn get_all_releases (
455
- Path ( params) : Path < CrateDetailHandlerParams > ,
457
+ Path ( params) : Path < RustdocHtmlParams > ,
456
458
mut conn : DbConnection ,
457
459
) -> AxumResult < AxumResponse > {
458
- let crate_id = sqlx:: query_scalar!(
460
+ let req_path: String = params. path . clone ( ) . unwrap_or_default ( ) ;
461
+ let req_path: Vec < & str > = req_path. split ( '/' ) . collect ( ) ;
462
+
463
+ let release_found = match_version ( & mut conn, & params. name , Some ( & params. version ) ) . await ?;
464
+ trace ! ( ?release_found, "found release" ) ;
465
+
466
+ let ( version, _) = match release_found. version {
467
+ MatchSemver :: Exact ( ( version, _) ) => ( version. clone ( ) , version) ,
468
+ MatchSemver :: Latest ( ( version, _) ) => ( version, "latest" . to_string ( ) ) ,
469
+ MatchSemver :: Semver ( _) => return Err ( AxumNope :: VersionNotFound ) ,
470
+ } ;
471
+
472
+ let row = sqlx:: query!(
459
473
"SELECT
460
- crates.id AS crate_id
474
+ crates.id AS crate_id,
475
+ releases.doc_targets
461
476
FROM crates
462
- WHERE crates.name = $1;" ,
477
+ INNER JOIN releases on crates.id = releases.crate_id
478
+ WHERE crates.name = $1 and releases.version = $2;" ,
463
479
params. name,
480
+ & version,
464
481
)
465
482
. fetch_optional ( & mut * conn)
466
- . await ?;
483
+ . await ?
484
+ . ok_or ( AxumNope :: CrateNotFound ) ?;
467
485
468
- let releases: Vec < Release > = if let Some ( crate_id) = crate_id {
469
- // get releases, sorted by semver
470
- releases_for_crate ( & mut conn, crate_id) . await ?
486
+ // get releases, sorted by semver
487
+ let releases: Vec < Release > = releases_for_crate ( & mut conn, row. crate_id ) . await ?;
488
+
489
+ let doc_targets = MetaData :: parse_doc_targets ( row. doc_targets ) ;
490
+
491
+ let inner;
492
+ let ( target, inner_path) = {
493
+ let mut inner_path = req_path. clone ( ) ;
494
+
495
+ let target = if inner_path. len ( ) > 1
496
+ && doc_targets
497
+ . iter ( )
498
+ . any ( |s| Some ( s) == params. target . as_ref ( ) )
499
+ {
500
+ inner_path. remove ( 0 ) ;
501
+ params. target . as_ref ( ) . unwrap ( )
502
+ } else {
503
+ ""
504
+ } ;
505
+
506
+ inner = inner_path. join ( "/" ) ;
507
+ ( target, inner. trim_end_matches ( '/' ) )
508
+ } ;
509
+ let inner_path = if inner_path. is_empty ( ) {
510
+ format ! ( "{}/index.html" , params. name)
471
511
} else {
472
- Vec :: new ( )
512
+ format ! ( "{}/{inner_path}" , params. name)
513
+ } ;
514
+
515
+ let target = if target. is_empty ( ) {
516
+ String :: new ( )
517
+ } else {
518
+ format ! ( "{target}/" )
473
519
} ;
474
520
475
521
let res = ReleaseList {
476
522
releases,
523
+ target : target. to_string ( ) ,
524
+ inner_path,
477
525
crate_name : params. name ,
478
526
} ;
479
527
Ok ( res. into_response ( ) )
0 commit comments