Skip to content

Commit 3a92f77

Browse files
Add --generate-redirect-map option to replace HTML redirection file with a unique JSON map
1 parent 15598a8 commit 3a92f77

File tree

3 files changed

+60
-12
lines changed

3 files changed

+60
-12
lines changed

src/librustdoc/config.rs

+4
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,8 @@ crate struct RenderOptions {
265265
crate document_private: bool,
266266
/// Document items that have `doc(hidden)`.
267267
crate document_hidden: bool,
268+
/// If `true`, generate a JSON file in the crate folder instead of HTML redirection files.
269+
crate generate_redirect_map: bool,
268270
crate unstable_features: rustc_feature::UnstableFeatures,
269271
}
270272

@@ -586,6 +588,7 @@ impl Options {
586588
let document_private = matches.opt_present("document-private-items");
587589
let document_hidden = matches.opt_present("document-hidden-items");
588590
let run_check = matches.opt_present("check");
591+
let generate_redirect_map = matches.opt_present("generate-redirect-map");
589592

590593
let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
591594

@@ -643,6 +646,7 @@ impl Options {
643646
generate_search_filter,
644647
document_private,
645648
document_hidden,
649+
generate_redirect_map,
646650
unstable_features: rustc_feature::UnstableFeatures::from_environment(
647651
crate_name.as_deref(),
648652
),

src/librustdoc/html/render/mod.rs

+49-12
Original file line numberDiff line numberDiff line change
@@ -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

src/librustdoc/lib.rs

+7
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,13 @@ fn opts() -> Vec<RustcOptGroup> {
423423
o.optopt("", "test-builder", "The rustc-like binary to use as the test builder", "PATH")
424424
}),
425425
unstable("check", |o| o.optflag("", "check", "Run rustdoc checks")),
426+
unstable("generate-redirect-map", |o| {
427+
o.optflag(
428+
"",
429+
"generate-redirect-map",
430+
"Generate JSON file at the top level instead of generating HTML redirection files",
431+
)
432+
}),
426433
]
427434
}
428435

0 commit comments

Comments
 (0)