if !foreign.is_empty() {
write!(w, "
- <h2 id='foreign-impls' class='section-header'>
+ <h2 id='foreign-impls' class='small-section-header'>
Implementations on Foreign Types<a href='#foreign-impls' class='anchor'></a>
</h2>
")?;
let mut links = HashSet::new();
let ret = v.iter()
.filter_map(|i| if let Some(ref i) = i.inner_impl().trait_ {
- let out = format!("{:#}", i).replace("<", "<").replace(">", ">");
+ let i_display = format!("{:#}", i);
+ let out = Escape(&i_display);
let encoded = small_url_encode(&format!("{:#}", i));
let generated = format!("<a href=\"#impl-{}\">{}</a>", encoded, out);
if !links.contains(&generated) && links.insert(generated.clone()) {
fn sidebar_struct(fmt: &mut fmt::Formatter, it: &clean::Item,
s: &clean::Struct) -> fmt::Result {
let mut sidebar = String::new();
+ let fields = get_struct_fields_name(&s.fields);
- if s.fields.iter()
- .any(|f| if let clean::StructFieldItem(..) = f.inner { true } else { false }) {
+ if !fields.is_empty() {
if let doctree::Plain = s.struct_type {
- sidebar.push_str("<li><a href=\"#fields\">Fields</a></li>");
+ sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#fields\">Fields</a>\
+ <div class=\"sidebar-links\">{}</div>", fields));
}
}
Ok(())
}
+fn extract_for_impl_name(item: &clean::Item) -> Option<(String, String)> {
+ match item.inner {
+ clean::ItemEnum::ImplItem(ref i) => {
+ if let Some(ref trait_) = i.trait_ {
+ Some((format!("{:#}", i.for_), format!("{:#}", trait_)))
+ } else {
+ None
+ }
+ },
+ _ => None,
+ }
+}
+
fn sidebar_trait(fmt: &mut fmt::Formatter, it: &clean::Item,
t: &clean::Trait) -> fmt::Result {
let mut sidebar = String::new();
- let has_types = t.items.iter().any(|m| m.is_associated_type());
- let has_consts = t.items.iter().any(|m| m.is_associated_const());
- let has_required = t.items.iter().any(|m| m.is_ty_method());
- let has_provided = t.items.iter().any(|m| m.is_method());
+ let types = t.items
+ .iter()
+ .filter_map(|m| {
+ match m.name {
+ Some(ref name) if m.is_associated_type() => {
+ Some(format!("<a href=\"#associatedtype.{name}\">{name}</a>",
+ name=name))
+ }
+ _ => None,
+ }
+ })
+ .collect::<String>();
+ let consts = t.items
+ .iter()
+ .filter_map(|m| {
+ match m.name {
+ Some(ref name) if m.is_associated_const() => {
+ Some(format!("<a href=\"#associatedconstant.{name}\">{name}</a>",
+ name=name))
+ }
+ _ => None,
+ }
+ })
+ .collect::<String>();
+ let required = t.items
+ .iter()
+ .filter_map(|m| {
+ match m.name {
+ Some(ref name) if m.is_ty_method() => {
+ Some(format!("<a href=\"#tymethod.{name}\">{name}</a>",
+ name=name))
+ }
+ _ => None,
+ }
+ })
+ .collect::<String>();
+ let provided = t.items
+ .iter()
+ .filter_map(|m| {
+ match m.name {
+ Some(ref name) if m.is_method() => {
+ Some(format!("<a href=\"#method.{name}\">{name}</a>", name=name))
+ }
+ _ => None,
+ }
+ })
+ .collect::<String>();
- if has_types {
- sidebar.push_str("<li><a href=\"#associated-types\">Associated Types</a></li>");
+ if !types.is_empty() {
+ sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#associated-types\">\
+ Associated Types</a><div class=\"sidebar-links\">{}</div>",
+ types));
}
- if has_consts {
- sidebar.push_str("<li><a href=\"#associated-const\">Associated Constants</a></li>");
+ if !consts.is_empty() {
+ sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#associated-const\">\
+ Associated Constants</a><div class=\"sidebar-links\">{}</div>",
+ consts));
}
- if has_required {
- sidebar.push_str("<li><a href=\"#required-methods\">Required Methods</a></li>");
+ if !required.is_empty() {
+ sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#required-methods\">\
+ Required Methods</a><div class=\"sidebar-links\">{}</div>",
+ required));
}
- if has_provided {
- sidebar.push_str("<li><a href=\"#provided-methods\">Provided Methods</a></li>");
+ if !provided.is_empty() {
+ sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#provided-methods\">\
+ Provided Methods</a><div class=\"sidebar-links\">{}</div>",
+ provided));
}
let c = cache();
if let Some(implementors) = c.implementors.get(&it.def_id) {
- if implementors.iter().any(|i| i.impl_.for_.def_id()
- .map_or(false, |d| !c.paths.contains_key(&d)))
- {
- sidebar.push_str("<li><a href=\"#foreign-impls\">\
- Implementations on Foreign Types</a></li>");
- }
- }
-
- sidebar.push_str("<li><a href=\"#implementors\">Implementors</a></li>");
+ let res = implementors.iter()
+ .filter(|i| i.impl_.for_.def_id()
+ .map_or(false, |d| !c.paths.contains_key(&d)))
+ .filter_map(|i| {
+ if let Some(item) = implementor2item(&c, i) {
+ match extract_for_impl_name(&item) {
+ Some((ref name, ref url)) => {
+ Some(format!("<a href=\"#impl-{}\">{}</a>",
+ small_url_encode(url),
+ Escape(name)))
+ }
+ _ => None,
+ }
+ } else {
+ None
+ }
+ })
+ .collect::<String>();
+ if !res.is_empty() {
+ sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#foreign-impls\">\
+ Implementations on Foreign Types</a><div \
+ class=\"sidebar-links\">{}</div>",
+ res));
+ }
+ }
+
+ sidebar.push_str("<a class=\"sidebar-title\" href=\"#implementors\">Implementors</a>");
sidebar.push_str(&sidebar_assoc_items(it));
Ok(())
}
+fn get_struct_fields_name(fields: &[clean::Item]) -> String {
+ fields.iter()
+ .filter(|f| if let clean::StructFieldItem(..) = f.inner {
+ true
+ } else {
+ false
+ })
+ .filter_map(|f| match f.name {
+ Some(ref name) => Some(format!("<a href=\"#structfield.{name}\">\
+ {name}</a>", name=name)),
+ _ => None,
+ })
+ .collect()
+}
+
fn sidebar_union(fmt: &mut fmt::Formatter, it: &clean::Item,
u: &clean::Union) -> fmt::Result {
let mut sidebar = String::new();
+ let fields = get_struct_fields_name(&u.fields);
- if u.fields.iter()
- .any(|f| if let clean::StructFieldItem(..) = f.inner { true } else { false }) {
- sidebar.push_str("<li><a href=\"#fields\">Fields</a></li>");
+ if !fields.is_empty() {
+ sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#fields\">Fields</a>\
+ <div class=\"sidebar-links\">{}</div>", fields));
}
sidebar.push_str(&sidebar_assoc_items(it));
e: &clean::Enum) -> fmt::Result {
let mut sidebar = String::new();
- if !e.variants.is_empty() {
- sidebar.push_str("<li><a href=\"#variants\">Variants</a></li>");
+ let variants = e.variants.iter()
+ .filter_map(|v| match v.name {
+ Some(ref name) => Some(format!("<a href=\"#variant.{name}\">{name}\
+ </a>", name = name)),
+ _ => None,
+ })
+ .collect::<String>();
+ if !variants.is_empty() {
+ sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#variants\">Variants</a>\
+ <div class=\"sidebar-links\">{}</div>", variants));
}
sidebar.push_str(&sidebar_assoc_items(it));
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_name = "foo"]
+
+// @has foo/trait.Foo.html
+// @has - '//*[@class="sidebar-title"][@href="#required-methods"]' 'Required Methods'
+// @has - '//*[@class="sidebar-links"]/a' 'bar'
+// @has - '//*[@class="sidebar-title"][@href="#provided-methods"]' 'Provided Methods'
+// @has - '//*[@class="sidebar-links"]/a' 'foo'
+// @has - '//*[@class="sidebar-title"][@href="#associated-const"]' 'Associated Constants'
+// @has - '//*[@class="sidebar-links"]/a' 'BAR'
+// @has - '//*[@class="sidebar-title"][@href="#associated-types"]' 'Associated Types'
+// @has - '//*[@class="sidebar-links"]/a' 'Output'
+pub trait Foo {
+ const BAR: u32 = 0;
+ type Output: ?Sized;
+
+ fn foo() {}
+ fn bar() -> Self::Output;
+}
+
+// @has foo/struct.Bar.html
+// @has - '//*[@class="sidebar-title"][@href="#fields"]' 'Fields'
+// @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f"]' 'f'
+// @has - '//*[@class="sidebar-links"]/a[@href="#structfield.u"]' 'u'
+// @!has - '//*[@class="sidebar-links"]/a' 'w'
+pub struct Bar {
+ pub f: u32,
+ pub u: u32,
+ w: u32,
+}
+
+// @has foo/enum.En.html
+// @has - '//*[@class="sidebar-title"][@href="#variants"]' 'Variants'
+// @has - '//*[@class="sidebar-links"]/a' 'foo'
+// @has - '//*[@class="sidebar-links"]/a' 'bar'
+pub enum En {
+ foo,
+ bar,
+}
+
+// @has foo/union.MyUnion.html
+// @has - '//*[@class="sidebar-title"][@href="#fields"]' 'Fields'
+// @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f1"]' 'f1'
+// @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f2"]' 'f2'
+// @!has - '//*[@class="sidebar-links"]/a' 'w'
+pub union MyUnion {
+ pub f1: u32,
+ pub f2: f32,
+ w: u32,
+}