Skip to content

Commit ac398a3

Browse files
Add more elements in the sidebar
1 parent 7f6417e commit ac398a3

File tree

2 files changed

+198
-31
lines changed

2 files changed

+198
-31
lines changed

src/librustdoc/html/render.rs

+139-31
Original file line numberDiff line numberDiff line change
@@ -2498,7 +2498,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
24982498

24992499
if !foreign.is_empty() {
25002500
write!(w, "
2501-
<h2 id='foreign-impls' class='section-header'>
2501+
<h2 id='foreign-impls' class='small-section-header'>
25022502
Implementations on Foreign Types<a href='#foreign-impls' class='anchor'></a>
25032503
</h2>
25042504
")?;
@@ -3591,7 +3591,8 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
35913591
let mut links = HashSet::new();
35923592
let ret = v.iter()
35933593
.filter_map(|i| if let Some(ref i) = i.inner_impl().trait_ {
3594-
let out = format!("{:#}", i).replace("<", "&lt;").replace(">", "&gt;");
3594+
let i_display = format!("{:#}", i);
3595+
let out = Escape(&i_display);
35953596
let encoded = small_url_encode(&format!("{:#}", i));
35963597
let generated = format!("<a href=\"#impl-{}\">{}</a>", encoded, out);
35973598
if !links.contains(&generated) && links.insert(generated.clone()) {
@@ -3617,11 +3618,12 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
36173618
fn sidebar_struct(fmt: &mut fmt::Formatter, it: &clean::Item,
36183619
s: &clean::Struct) -> fmt::Result {
36193620
let mut sidebar = String::new();
3621+
let fields = get_struct_fields_name(&s.fields);
36203622

3621-
if s.fields.iter()
3622-
.any(|f| if let clean::StructFieldItem(..) = f.inner { true } else { false }) {
3623+
if !fields.is_empty() {
36233624
if let doctree::Plain = s.struct_type {
3624-
sidebar.push_str("<li><a href=\"#fields\">Fields</a></li>");
3625+
sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#fields\">Fields</a>\
3626+
<div class=\"sidebar-links\">{}</div>", fields));
36253627
}
36263628
}
36273629

@@ -3633,40 +3635,122 @@ fn sidebar_struct(fmt: &mut fmt::Formatter, it: &clean::Item,
36333635
Ok(())
36343636
}
36353637

3638+
fn extract_for_impl_name(item: &clean::Item) -> Option<(String, String)> {
3639+
match item.inner {
3640+
clean::ItemEnum::ImplItem(ref i) => {
3641+
if let Some(ref trait_) = i.trait_ {
3642+
Some((format!("{:#}", i.for_), format!("{:#}", trait_)))
3643+
} else {
3644+
None
3645+
}
3646+
},
3647+
_ => None,
3648+
}
3649+
}
3650+
36363651
fn sidebar_trait(fmt: &mut fmt::Formatter, it: &clean::Item,
36373652
t: &clean::Trait) -> fmt::Result {
36383653
let mut sidebar = String::new();
36393654

3640-
let has_types = t.items.iter().any(|m| m.is_associated_type());
3641-
let has_consts = t.items.iter().any(|m| m.is_associated_const());
3642-
let has_required = t.items.iter().any(|m| m.is_ty_method());
3643-
let has_provided = t.items.iter().any(|m| m.is_method());
3655+
let types = t.items
3656+
.iter()
3657+
.filter_map(|m| {
3658+
match m.name {
3659+
Some(ref name) if m.is_associated_type() => {
3660+
Some(format!("<a href=\"#associatedtype.{name}\">{name}</a>",
3661+
name=name))
3662+
}
3663+
_ => None,
3664+
}
3665+
})
3666+
.collect::<String>();
3667+
let consts = t.items
3668+
.iter()
3669+
.filter_map(|m| {
3670+
match m.name {
3671+
Some(ref name) if m.is_associated_const() => {
3672+
Some(format!("<a href=\"#associatedconstant.{name}\">{name}</a>",
3673+
name=name))
3674+
}
3675+
_ => None,
3676+
}
3677+
})
3678+
.collect::<String>();
3679+
let required = t.items
3680+
.iter()
3681+
.filter_map(|m| {
3682+
match m.name {
3683+
Some(ref name) if m.is_ty_method() => {
3684+
Some(format!("<a href=\"#tymethod.{name}\">{name}</a>",
3685+
name=name))
3686+
}
3687+
_ => None,
3688+
}
3689+
})
3690+
.collect::<String>();
3691+
let provided = t.items
3692+
.iter()
3693+
.filter_map(|m| {
3694+
match m.name {
3695+
Some(ref name) if m.is_method() => {
3696+
Some(format!("<a href=\"#method.{name}\">{name}</a>", name=name))
3697+
}
3698+
_ => None,
3699+
}
3700+
})
3701+
.collect::<String>();
36443702

3645-
if has_types {
3646-
sidebar.push_str("<li><a href=\"#associated-types\">Associated Types</a></li>");
3703+
if !types.is_empty() {
3704+
sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#associated-types\">\
3705+
Associated Types</a><div class=\"sidebar-links\">{}</div>",
3706+
types));
36473707
}
3648-
if has_consts {
3649-
sidebar.push_str("<li><a href=\"#associated-const\">Associated Constants</a></li>");
3708+
if !consts.is_empty() {
3709+
sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#associated-const\">\
3710+
Associated Constants</a><div class=\"sidebar-links\">{}</div>",
3711+
consts));
36503712
}
3651-
if has_required {
3652-
sidebar.push_str("<li><a href=\"#required-methods\">Required Methods</a></li>");
3713+
if !required.is_empty() {
3714+
sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#required-methods\">\
3715+
Required Methods</a><div class=\"sidebar-links\">{}</div>",
3716+
required));
36533717
}
3654-
if has_provided {
3655-
sidebar.push_str("<li><a href=\"#provided-methods\">Provided Methods</a></li>");
3718+
if !provided.is_empty() {
3719+
sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#provided-methods\">\
3720+
Provided Methods</a><div class=\"sidebar-links\">{}</div>",
3721+
provided));
36563722
}
36573723

36583724
let c = cache();
36593725

36603726
if let Some(implementors) = c.implementors.get(&it.def_id) {
3661-
if implementors.iter().any(|i| i.impl_.for_.def_id()
3662-
.map_or(false, |d| !c.paths.contains_key(&d)))
3663-
{
3664-
sidebar.push_str("<li><a href=\"#foreign-impls\">\
3665-
Implementations on Foreign Types</a></li>");
3666-
}
3667-
}
3668-
3669-
sidebar.push_str("<li><a href=\"#implementors\">Implementors</a></li>");
3727+
let res = implementors.iter()
3728+
.filter(|i| i.impl_.for_.def_id()
3729+
.map_or(false, |d| !c.paths.contains_key(&d)))
3730+
.filter_map(|i| {
3731+
if let Some(item) = implementor2item(&c, i) {
3732+
match extract_for_impl_name(&item) {
3733+
Some((ref name, ref url)) => {
3734+
Some(format!("<a href=\"#impl-{}\">{}</a>",
3735+
small_url_encode(url),
3736+
Escape(name)))
3737+
}
3738+
_ => None,
3739+
}
3740+
} else {
3741+
None
3742+
}
3743+
})
3744+
.collect::<String>();
3745+
if !res.is_empty() {
3746+
sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#foreign-impls\">\
3747+
Implementations on Foreign Types</a><div \
3748+
class=\"sidebar-links\">{}</div>",
3749+
res));
3750+
}
3751+
}
3752+
3753+
sidebar.push_str("<a class=\"sidebar-title\" href=\"#implementors\">Implementors</a>");
36703754

36713755
sidebar.push_str(&sidebar_assoc_items(it));
36723756

@@ -3693,13 +3777,29 @@ fn sidebar_typedef(fmt: &mut fmt::Formatter, it: &clean::Item,
36933777
Ok(())
36943778
}
36953779

3780+
fn get_struct_fields_name(fields: &[clean::Item]) -> String {
3781+
fields.iter()
3782+
.filter(|f| if let clean::StructFieldItem(..) = f.inner {
3783+
true
3784+
} else {
3785+
false
3786+
})
3787+
.filter_map(|f| match f.name {
3788+
Some(ref name) => Some(format!("<a href=\"#structfield.{name}\">\
3789+
{name}</a>", name=name)),
3790+
_ => None,
3791+
})
3792+
.collect()
3793+
}
3794+
36963795
fn sidebar_union(fmt: &mut fmt::Formatter, it: &clean::Item,
36973796
u: &clean::Union) -> fmt::Result {
36983797
let mut sidebar = String::new();
3798+
let fields = get_struct_fields_name(&u.fields);
36993799

3700-
if u.fields.iter()
3701-
.any(|f| if let clean::StructFieldItem(..) = f.inner { true } else { false }) {
3702-
sidebar.push_str("<li><a href=\"#fields\">Fields</a></li>");
3800+
if !fields.is_empty() {
3801+
sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#fields\">Fields</a>\
3802+
<div class=\"sidebar-links\">{}</div>", fields));
37033803
}
37043804

37053805
sidebar.push_str(&sidebar_assoc_items(it));
@@ -3714,8 +3814,16 @@ fn sidebar_enum(fmt: &mut fmt::Formatter, it: &clean::Item,
37143814
e: &clean::Enum) -> fmt::Result {
37153815
let mut sidebar = String::new();
37163816

3717-
if !e.variants.is_empty() {
3718-
sidebar.push_str("<li><a href=\"#variants\">Variants</a></li>");
3817+
let variants = e.variants.iter()
3818+
.filter_map(|v| match v.name {
3819+
Some(ref name) => Some(format!("<a href=\"#variant.{name}\">{name}\
3820+
</a>", name = name)),
3821+
_ => None,
3822+
})
3823+
.collect::<String>();
3824+
if !variants.is_empty() {
3825+
sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#variants\">Variants</a>\
3826+
<div class=\"sidebar-links\">{}</div>", variants));
37193827
}
37203828

37213829
sidebar.push_str(&sidebar_assoc_items(it));

src/test/rustdoc/sidebar-items.rs

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![crate_name = "foo"]
12+
13+
// @has foo/trait.Foo.html
14+
// @has - '//*[@class="sidebar-title"][@href="#required-methods"]' 'Required Methods'
15+
// @has - '//*[@class="sidebar-links"]/a' 'bar'
16+
// @has - '//*[@class="sidebar-title"][@href="#provided-methods"]' 'Provided Methods'
17+
// @has - '//*[@class="sidebar-links"]/a' 'foo'
18+
// @has - '//*[@class="sidebar-title"][@href="#associated-const"]' 'Associated Constants'
19+
// @has - '//*[@class="sidebar-links"]/a' 'BAR'
20+
// @has - '//*[@class="sidebar-title"][@href="#associated-types"]' 'Associated Types'
21+
// @has - '//*[@class="sidebar-links"]/a' 'Output'
22+
pub trait Foo {
23+
const BAR: u32 = 0;
24+
type Output: ?Sized;
25+
26+
fn foo() {}
27+
fn bar() -> Self::Output;
28+
}
29+
30+
// @has foo/struct.Bar.html
31+
// @has - '//*[@class="sidebar-title"][@href="#fields"]' 'Fields'
32+
// @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f"]' 'f'
33+
// @has - '//*[@class="sidebar-links"]/a[@href="#structfield.u"]' 'u'
34+
// @!has - '//*[@class="sidebar-links"]/a' 'w'
35+
pub struct Bar {
36+
pub f: u32,
37+
pub u: u32,
38+
w: u32,
39+
}
40+
41+
// @has foo/enum.En.html
42+
// @has - '//*[@class="sidebar-title"][@href="#variants"]' 'Variants'
43+
// @has - '//*[@class="sidebar-links"]/a' 'foo'
44+
// @has - '//*[@class="sidebar-links"]/a' 'bar'
45+
pub enum En {
46+
foo,
47+
bar,
48+
}
49+
50+
// @has foo/union.MyUnion.html
51+
// @has - '//*[@class="sidebar-title"][@href="#fields"]' 'Fields'
52+
// @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f1"]' 'f1'
53+
// @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f2"]' 'f2'
54+
// @!has - '//*[@class="sidebar-links"]/a' 'w'
55+
pub union MyUnion {
56+
pub f1: u32,
57+
pub f2: f32,
58+
w: u32,
59+
}

0 commit comments

Comments
 (0)