@@ -111,6 +111,10 @@ crate struct Context<'tcx> {
111
111
/// real location of an item. This is used to allow external links to
112
112
/// publicly reused items to redirect to the right location.
113
113
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 > > > > ,
114
118
/// The map used to ensure all generated 'id=' attributes are unique.
115
119
id_map : Rc < RefCell < IdMap > > ,
116
120
/// Tracks section IDs for `Deref` targets so they match in both the main
@@ -405,6 +409,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
405
409
static_root_path,
406
410
generate_search_filter,
407
411
unstable_features,
412
+ generate_redirect_map,
408
413
..
409
414
} = options;
410
415
@@ -510,6 +515,11 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
510
515
all : Rc :: new ( RefCell :: new ( AllTypes :: new ( ) ) ) ,
511
516
errors : Rc :: new ( receiver) ,
512
517
cache : Rc :: new ( cache) ,
518
+ redirections : if generate_redirect_map {
519
+ Some ( Rc :: new ( RefCell :: new ( FxHashMap :: default ( ) ) ) )
520
+ } else {
521
+ None
522
+ } ,
513
523
} ;
514
524
515
525
CURRENT_DEPTH . with ( |s| s. set ( 0 ) ) ;
@@ -588,6 +598,15 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
588
598
& style_files,
589
599
) ;
590
600
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
+ }
591
610
592
611
// Flush pending errors.
593
612
Arc :: get_mut ( & mut self . shared ) . unwrap ( ) . fs . close ( ) ;
@@ -664,9 +683,9 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
664
683
if !buf. is_empty ( ) {
665
684
let name = item. name . as_ref ( ) . unwrap ( ) ;
666
685
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 ( ) ) ;
668
687
self . shared . ensure_dir ( & self . dst ) ?;
669
- let joint_dst = self . dst . join ( file_name) ;
688
+ let joint_dst = self . dst . join ( & file_name) ;
670
689
self . shared . fs . write ( & joint_dst, buf. as_bytes ( ) ) ?;
671
690
672
691
if !self . render_redirect_pages {
@@ -676,9 +695,17 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
676
695
// to the new one (without).
677
696
if item_type == ItemType :: Macro {
678
697
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
+ }
682
709
}
683
710
}
684
711
Ok ( ( ) )
@@ -1588,17 +1615,27 @@ impl Context<'_> {
1588
1615
& self . shared . style_files ,
1589
1616
)
1590
1617
} else {
1591
- let mut url = self . root_path ( ) ;
1592
1618
if let Some ( & ( ref names, ty) ) = self . cache . paths . get ( & it. def_id ) {
1619
+ let mut path = String :: new ( ) ;
1593
1620
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) ) ,
1596
1636
}
1597
- url. push_str ( & item_path ( ty, names. last ( ) . unwrap ( ) ) ) ;
1598
- layout:: redirect ( & url)
1599
- } else {
1600
- String :: new ( )
1601
1637
}
1638
+ String :: new ( )
1602
1639
}
1603
1640
}
1604
1641
0 commit comments