@@ -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
@@ -404,6 +408,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
404408 static_root_path,
405409 generate_search_filter,
406410 unstable_features,
411+ generate_redirect_map,
407412 ..
408413 } = options;
409414
@@ -509,6 +514,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
509514 all : Rc :: new ( RefCell :: new ( AllTypes :: new ( ) ) ) ,
510515 errors : Rc :: new ( receiver) ,
511516 cache : Rc :: new ( cache) ,
517+ redirections : if generate_redirect_map { Some ( Default :: default ( ) ) } else { None } ,
512518 } ;
513519
514520 CURRENT_DEPTH . with ( |s| s. set ( 0 ) ) ;
@@ -587,6 +593,15 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
587593 & style_files,
588594 ) ;
589595 self . shared . fs . write ( & settings_file, v. as_bytes ( ) ) ?;
596+ if let Some ( redirections) = self . redirections . take ( ) {
597+ if !redirections. borrow ( ) . is_empty ( ) {
598+ let redirect_map_path =
599+ self . dst . join ( & * krate. name . as_str ( ) ) . join ( "redirect-map.json" ) ;
600+ let paths = serde_json:: to_string ( & * redirections. borrow ( ) ) . unwrap ( ) ;
601+ self . shared . ensure_dir ( & self . dst . join ( & * krate. name . as_str ( ) ) ) ?;
602+ self . shared . fs . write ( & redirect_map_path, paths. as_bytes ( ) ) ?;
603+ }
604+ }
590605
591606 // Flush pending errors.
592607 Arc :: get_mut ( & mut self . shared ) . unwrap ( ) . fs . close ( ) ;
@@ -675,9 +690,17 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
675690 // to the new one (without).
676691 if item_type == ItemType :: Macro {
677692 let redir_name = format ! ( "{}.{}!.html" , item_type, name) ;
678- let redir_dst = self . dst . join ( redir_name) ;
679- let v = layout:: redirect ( file_name) ;
680- self . shared . fs . write ( & redir_dst, v. as_bytes ( ) ) ?;
693+ if let Some ( ref redirections) = self . redirections {
694+ let crate_name = & self . shared . layout . krate ;
695+ redirections. borrow_mut ( ) . insert (
696+ format ! ( "{}/{}" , crate_name, redir_name) ,
697+ format ! ( "{}/{}" , crate_name, file_name) ,
698+ ) ;
699+ } else {
700+ let v = layout:: redirect ( file_name) ;
701+ let redir_dst = self . dst . join ( redir_name) ;
702+ self . shared . fs . write ( & redir_dst, v. as_bytes ( ) ) ?;
703+ }
681704 }
682705 }
683706 Ok ( ( ) )
@@ -1588,17 +1611,27 @@ impl Context<'_> {
15881611 & self . shared . style_files ,
15891612 )
15901613 } else {
1591- let mut url = self . root_path ( ) ;
15921614 if let Some ( & ( ref names, ty) ) = self . cache . paths . get ( & it. def_id ) {
1615+ let mut path = String :: new ( ) ;
15931616 for name in & names[ ..names. len ( ) - 1 ] {
1594- url. push_str ( name) ;
1595- url. push ( '/' ) ;
1617+ path. push_str ( name) ;
1618+ path. push ( '/' ) ;
1619+ }
1620+ path. push_str ( & item_path ( ty, names. last ( ) . unwrap ( ) ) ) ;
1621+ match self . redirections {
1622+ Some ( ref redirections) => {
1623+ let mut current_path = String :: new ( ) ;
1624+ for name in & self . current {
1625+ current_path. push_str ( name) ;
1626+ current_path. push ( '/' ) ;
1627+ }
1628+ current_path. push_str ( & item_path ( ty, names. last ( ) . unwrap ( ) ) ) ;
1629+ redirections. borrow_mut ( ) . insert ( current_path, path) ;
1630+ }
1631+ None => return layout:: redirect ( & format ! ( "{}{}" , self . root_path( ) , path) ) ,
15961632 }
1597- url. push_str ( & item_path ( ty, names. last ( ) . unwrap ( ) ) ) ;
1598- layout:: redirect ( & url)
1599- } else {
1600- String :: new ( )
16011633 }
1634+ String :: new ( )
16021635 }
16031636 }
16041637
0 commit comments