Skip to content

Commit 525b77e

Browse files
committed
rustdoc: redirects from sane, namespaced URLs to Rustdoc's ridiculous ones
cc #35020 which does this properly
1 parent b6bd1ce commit 525b77e

File tree

2 files changed

+48
-17
lines changed

2 files changed

+48
-17
lines changed

src/librustdoc/html/item_type.rs

+6
Original file line numberDiff line numberDiff line change
@@ -168,3 +168,9 @@ impl NameSpace {
168168
}
169169
}
170170
}
171+
172+
impl fmt::Display for NameSpace {
173+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
174+
self.to_static_str().fmt(f)
175+
}
176+
}

src/librustdoc/html/render.rs

+42-17
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ use std::collections::{BTreeMap, HashMap, HashSet};
4141
use std::default::Default;
4242
use std::error;
4343
use std::fmt::{self, Display, Formatter};
44-
use std::fs::{self, File};
44+
use std::fs::{self, File, OpenOptions};
4545
use std::io::prelude::*;
4646
use std::io::{self, BufWriter, BufReader};
4747
use std::iter::repeat;
@@ -1409,11 +1409,23 @@ impl Context {
14091409
self.render_item(&mut buf, &item, true).unwrap();
14101410
// buf will be empty if the item is stripped and there is no redirect for it
14111411
if !buf.is_empty() {
1412-
let joint_dst = self.dst.join(&item_path(item_type(&item),
1413-
item.name.as_ref().unwrap()));
1412+
let name = item.name.as_ref().unwrap();
1413+
let item_type = item_type(&item);
1414+
let file_name = &item_path(item_type, name);
1415+
let joint_dst = self.dst.join(file_name);
14141416
try_err!(fs::create_dir_all(&self.dst), &self.dst);
14151417
let mut dst = try_err!(File::create(&joint_dst), &joint_dst);
14161418
try_err!(dst.write_all(&buf), &joint_dst);
1419+
1420+
// Redirect from a sane URL using the namespace to Rustdoc's
1421+
// URL for the page.
1422+
let redir_name = format!("{}.{}.html", name, item_type.name_space());
1423+
let redir_dst = self.dst.join(redir_name);
1424+
if let Ok(mut redirect_out) = OpenOptions::new().create_new(true)
1425+
.write(true)
1426+
.open(&redir_dst) {
1427+
try_err!(layout::redirect(&mut redirect_out, file_name), &redir_dst);
1428+
}
14171429
}
14181430
}
14191431
Ok(())
@@ -2270,9 +2282,12 @@ fn item_struct(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
22702282
if fields.peek().is_some() {
22712283
write!(w, "<h2 class='fields'>Fields</h2>")?;
22722284
for (field, ty) in fields {
2273-
write!(w, "<span id='{item_type}.{name}' class='{item_type}'><code>{name}: {ty}</code>
2274-
</span><span class='stab {stab}'></span>",
2285+
write!(w, "<span id='{item_type}.{name}' class='{item_type}'>
2286+
<a id='{name}.{name_space}'>
2287+
<code>{name}: {ty}</code>
2288+
</a></span><span class='stab {stab}'></span>",
22752289
item_type = ItemType::StructField,
2290+
name_space = ItemType::StructField.name_space(),
22762291
stab = field.stability_class(),
22772292
name = field.name.as_ref().unwrap(),
22782293
ty = ty)?;
@@ -2341,8 +2356,10 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
23412356
if !e.variants.is_empty() {
23422357
write!(w, "<h2 class='variants'>Variants</h2>\n")?;
23432358
for variant in &e.variants {
2344-
write!(w, "<span id='{item_type}.{name}' class='variant'><code>{name}",
2359+
write!(w, "<span id='{item_type}.{name}' class='variant'>\
2360+
<a id='{name}.{name_space}'><code>{name}",
23452361
item_type = ItemType::Variant,
2362+
name_space = ItemType::Variant.name_space(),
23462363
name = variant.name.as_ref().unwrap())?;
23472364
if let clean::VariantItem(ref var) = variant.inner {
23482365
if let clean::TupleVariant(ref tys) = var.kind {
@@ -2356,7 +2373,7 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
23562373
write!(w, ")")?;
23572374
}
23582375
}
2359-
write!(w, "</code></span>")?;
2376+
write!(w, "</code></a></span>")?;
23602377
document(w, cx, variant)?;
23612378

23622379
use clean::{Variant, StructVariant};
@@ -2368,9 +2385,12 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
23682385
if let StructFieldItem(ref ty) = field.inner {
23692386
write!(w, "<tr><td \
23702387
id='variant.{v}.field.{f}'>\
2371-
<code>{f}:&nbsp;{t}</code></td><td>",
2388+
<a id='{v}.{vns}.{f}.{fns}'>\
2389+
<code>{f}:&nbsp;{t}</code></a></td><td>",
23722390
v = variant.name.as_ref().unwrap(),
23732391
f = field.name.as_ref().unwrap(),
2392+
vns = ItemType::Variant.name_space(),
2393+
fns = ItemType::StructField.name_space(),
23742394
t = *ty)?;
23752395
document(w, cx, field)?;
23762396
write!(w, "</td></tr>")?;
@@ -2605,36 +2625,41 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
26052625
if !is_static || render_static {
26062626
let id = derive_id(format!("{}.{}", item_type, name));
26072627
write!(w, "<h4 id='{}' class='{}'>", id, item_type)?;
2628+
write!(w, "<a id='{}.{}'>", name, item_type.name_space())?;
26082629
write!(w, "<code>")?;
26092630
render_assoc_item(w, item, link.anchor(&id))?;
26102631
write!(w, "</code>")?;
26112632
render_stability_since_raw(w, item.stable_since(), outer_version)?;
2612-
write!(w, "</h4>\n")?;
2633+
write!(w, "</a></h4>\n")?;
26132634
}
26142635
}
26152636
clean::TypedefItem(ref tydef, _) => {
26162637
let id = derive_id(format!("{}.{}", ItemType::AssociatedType, name));
2617-
write!(w, "<h4 id='{}' class='{}'><code>", id, item_type)?;
2638+
write!(w, "<h4 id='{}' class='{}'>", id, item_type)?;
2639+
write!(w, "<a id='{}.{}'><code>", name, item_type.name_space())?;
26182640
assoc_type(w, item, &Vec::new(), Some(&tydef.type_), link.anchor(&id))?;
2619-
write!(w, "</code></h4>\n")?;
2641+
write!(w, "</code></a></h4>\n")?;
26202642
}
26212643
clean::AssociatedConstItem(ref ty, ref default) => {
26222644
let id = derive_id(format!("{}.{}", item_type, name));
2623-
write!(w, "<h4 id='{}' class='{}'><code>", id, item_type)?;
2645+
write!(w, "<h4 id='{}' class='{}'>", id, item_type)?;
2646+
write!(w, "<a id='{}.{}'><code>", name, item_type.name_space())?;
26242647
assoc_const(w, item, ty, default.as_ref(), link.anchor(&id))?;
2625-
write!(w, "</code></h4>\n")?;
2648+
write!(w, "</code></a></h4>\n")?;
26262649
}
26272650
clean::ConstantItem(ref c) => {
26282651
let id = derive_id(format!("{}.{}", item_type, name));
2629-
write!(w, "<h4 id='{}' class='{}'><code>", id, item_type)?;
2652+
write!(w, "<h4 id='{}' class='{}'>", id, item_type)?;
2653+
write!(w, "<a id='{}.{}'><code>", name, item_type.name_space())?;
26302654
assoc_const(w, item, &c.type_, Some(&c.expr), link.anchor(&id))?;
2631-
write!(w, "</code></h4>\n")?;
2655+
write!(w, "</code></a></h4>\n")?;
26322656
}
26332657
clean::AssociatedTypeItem(ref bounds, ref default) => {
26342658
let id = derive_id(format!("{}.{}", item_type, name));
2635-
write!(w, "<h4 id='{}' class='{}'><code>", id, item_type)?;
2659+
write!(w, "<h4 id='{}' class='{}'>", id, item_type)?;
2660+
write!(w, "<a id='{}.{}'><code>", name, item_type.name_space())?;
26362661
assoc_type(w, item, bounds, default.as_ref(), link.anchor(&id))?;
2637-
write!(w, "</code></h4>\n")?;
2662+
write!(w, "</code></a></h4>\n")?;
26382663
}
26392664
clean::StrippedItem(..) => return Ok(()),
26402665
_ => panic!("can't make docs for trait item with name {:?}", item.name)

0 commit comments

Comments
 (0)