@@ -111,6 +111,10 @@ crate struct Context<'tcx> {
111111 /// real location of an item. This is used to allow external links to
112112 /// publicly reused items to redirect to the right location.
113113 crate render_redirect_pages : bool ,
114+ /// `None` by default, depends on the `generate-redirect-map` option flag. If this field is set
115+ /// to `Some(...)`, it'll store redirections and then generate a JSON file at the top level of
116+ /// the crate.
117+ crate redirections : Option < Rc < RefCell < FxHashMap < String , String > > > > ,
114118 /// The map used to ensure all generated 'id=' attributes are unique.
115119 id_map : Rc < RefCell < IdMap > > ,
116120 /// Tracks section IDs for `Deref` targets so they match in both the main
@@ -405,6 +409,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
405409 static_root_path,
406410 generate_search_filter,
407411 unstable_features,
412+ generate_redirect_map,
408413 ..
409414 } = options;
410415
@@ -510,6 +515,11 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
510515 all : Rc :: new ( RefCell :: new ( AllTypes :: new ( ) ) ) ,
511516 errors : Rc :: new ( receiver) ,
512517 cache : Rc :: new ( cache) ,
518+ redirections : if generate_redirect_map {
519+ Some ( Rc :: new ( RefCell :: new ( FxHashMap :: default ( ) ) ) )
520+ } else {
521+ None
522+ } ,
513523 } ;
514524
515525 CURRENT_DEPTH . with ( |s| s. set ( 0 ) ) ;
@@ -588,6 +598,15 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
588598 & style_files,
589599 ) ;
590600 self . shared . fs . write ( & settings_file, v. as_bytes ( ) ) ?;
601+ if let Some ( redirections) = self . redirections . take ( ) {
602+ if !redirections. borrow ( ) . is_empty ( ) {
603+ let redirect_map_path =
604+ self . dst . join ( & * krate. name . as_str ( ) ) . join ( "redirect-map.json" ) ;
605+ let paths = serde_json:: to_string ( & * redirections. borrow ( ) ) . unwrap ( ) ;
606+ self . shared . ensure_dir ( & self . dst . join ( & * krate. name . as_str ( ) ) ) ?;
607+ self . shared . fs . write ( & redirect_map_path, paths. as_bytes ( ) ) ?;
608+ }
609+ }
591610
592611 // Flush pending errors.
593612 Arc :: get_mut ( & mut self . shared ) . unwrap ( ) . fs . close ( ) ;
@@ -664,9 +683,9 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
664683 if !buf. is_empty ( ) {
665684 let name = item. name . as_ref ( ) . unwrap ( ) ;
666685 let item_type = item. type_ ( ) ;
667- let file_name = & item_path ( item_type, & name. as_str ( ) ) ;
686+ let file_name = item_path ( item_type, & name. as_str ( ) ) ;
668687 self . shared . ensure_dir ( & self . dst ) ?;
669- let joint_dst = self . dst . join ( file_name) ;
688+ let joint_dst = self . dst . join ( & file_name) ;
670689 self . shared . fs . write ( & joint_dst, buf. as_bytes ( ) ) ?;
671690
672691 if !self . render_redirect_pages {
@@ -676,9 +695,17 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
676695 // to the new one (without).
677696 if item_type == ItemType :: Macro {
678697 let redir_name = format ! ( "{}.{}!.html" , item_type, name) ;
679- let redir_dst = self . dst . join ( redir_name) ;
680- let v = layout:: redirect ( file_name) ;
681- self . shared . fs . write ( & redir_dst, v. as_bytes ( ) ) ?;
698+ if let Some ( ref redirections) = self . redirections {
699+ let crate_name = & self . shared . layout . krate ;
700+ redirections. borrow_mut ( ) . insert (
701+ format ! ( "{}/{}" , crate_name, redir_name) ,
702+ format ! ( "{}/{}" , crate_name, file_name) ,
703+ ) ;
704+ } else {
705+ let v = layout:: redirect ( & file_name) ;
706+ let redir_dst = self . dst . join ( redir_name) ;
707+ self . shared . fs . write ( & redir_dst, v. as_bytes ( ) ) ?;
708+ }
682709 }
683710 }
684711 Ok ( ( ) )
@@ -1588,17 +1615,27 @@ impl Context<'_> {
15881615 & self . shared . style_files ,
15891616 )
15901617 } else {
1591- let mut url = self . root_path ( ) ;
15921618 if let Some ( & ( ref names, ty) ) = self . cache . paths . get ( & it. def_id ) {
1619+ let mut path = String :: new ( ) ;
15931620 for name in & names[ ..names. len ( ) - 1 ] {
1594- url. push_str ( name) ;
1595- url. push ( '/' ) ;
1621+ path. push_str ( name) ;
1622+ path. push ( '/' ) ;
1623+ }
1624+ path. push_str ( & item_path ( ty, names. last ( ) . unwrap ( ) ) ) ;
1625+ match self . redirections {
1626+ Some ( ref redirections) => {
1627+ let mut current_path = String :: new ( ) ;
1628+ for name in & self . current {
1629+ current_path. push_str ( name) ;
1630+ current_path. push ( '/' ) ;
1631+ }
1632+ current_path. push_str ( & item_path ( ty, names. last ( ) . unwrap ( ) ) ) ;
1633+ redirections. borrow_mut ( ) . insert ( current_path, path) ;
1634+ }
1635+ None => return layout:: redirect ( & format ! ( "{}{}" , self . root_path( ) , path) ) ,
15961636 }
1597- url. push_str ( & item_path ( ty, names. last ( ) . unwrap ( ) ) ) ;
1598- layout:: redirect ( & url)
1599- } else {
1600- String :: new ( )
16011637 }
1638+ String :: new ( )
16021639 }
16031640 }
16041641
0 commit comments