diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 72702dc8d94..8b65a7d6791 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -313,6 +313,22 @@ impl Item { pub fn is_fn(&self) -> bool { match self.inner { FunctionItem(..) => true, _ => false } } + + pub fn stability_class(&self) -> String { + match self.stability { + Some(ref s) => { + let mut base = match s.level { + attr::Unstable => "unstable".to_string(), + attr::Stable => String::new(), + }; + if s.deprecated_since.len() > 0 { + base.push_str(" deprecated"); + } + base + } + _ => String::new(), + } + } } #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index d2dccca362e..8b6969f586e 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -23,10 +23,8 @@ use syntax::ast; use syntax::ast_util; use clean; -use stability_summary::ModuleSummary; use html::item_type::ItemType; use html::render; -use html::escape::Escape; use html::render::{cache, CURRENT_LOCATION_KEY}; /// Helper to render an optional visibility with a space after it (if the @@ -45,10 +43,6 @@ pub struct MutableSpace(pub clean::Mutability); /// Similar to VisSpace, but used for mutability #[derive(Copy, Clone)] pub struct RawMutableSpace(pub clean::Mutability); -/// Wrapper struct for properly emitting the stability level. -pub struct Stability<'a>(pub &'a Option); -/// Wrapper struct for emitting the stability level concisely. -pub struct ConciseStability<'a>(pub &'a Option); /// Wrapper struct for emitting a where clause from Generics. pub struct WhereClause<'a>(pub &'a clean::Generics); /// Wrapper struct for emitting type parameter bounds. @@ -702,119 +696,3 @@ impl fmt::Display for AbiSpace { } } } - -impl<'a> fmt::Display for Stability<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let Stability(stab) = *self; - match *stab { - Some(ref stability) => { - let lvl = if stability.deprecated_since.is_empty() { - format!("{}", stability.level) - } else { - "Deprecated".to_string() - }; - write!(f, "{lvl}", - lvl = Escape(&*lvl), - reason = Escape(&*stability.reason)) - } - None => Ok(()) - } - } -} - -impl<'a> fmt::Display for ConciseStability<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let ConciseStability(stab) = *self; - match *stab { - Some(ref stability) => { - let lvl = if stability.deprecated_since.is_empty() { - format!("{}", stability.level) - } else { - "Deprecated".to_string() - }; - write!(f, "", - lvl = Escape(&*lvl), - colon = if !stability.reason.is_empty() { ": " } else { "" }, - reason = Escape(&*stability.reason)) - } - None => { - write!(f, "") - } - } - } -} - -impl fmt::Display for ModuleSummary { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fn fmt_inner<'a>(f: &mut fmt::Formatter, - context: &mut Vec<&'a str>, - m: &'a ModuleSummary) - -> fmt::Result { - let cnt = m.counts; - let tot = cnt.total(); - if tot == 0 { return Ok(()) } - - context.push(&m.name); - let path = context.connect("::"); - - try!(write!(f, "")); - try!(write!(f, "{}", { - let mut url = context[1..].to_vec(); - url.push("index.html"); - url.connect("/") - }, - path)); - try!(write!(f, "")); - try!(write!(f, " ", - (100 * cnt.stable) as f64/tot as f64)); - try!(write!(f, " ", - (100 * cnt.unstable) as f64/tot as f64)); - try!(write!(f, " ", - (100 * cnt.deprecated) as f64/tot as f64)); - try!(write!(f, " ", - (100 * cnt.unmarked) as f64/tot as f64)); - try!(write!(f, "")); - - for submodule in &m.submodules { - try!(fmt_inner(f, context, submodule)); - } - context.pop(); - Ok(()) - } - - let mut context = Vec::new(); - - let tot = self.counts.total(); - let (stable, unstable, deprecated, unmarked) = if tot == 0 { - (0, 0, 0, 0) - } else { - ((100 * self.counts.stable)/tot, - (100 * self.counts.unstable)/tot, - (100 * self.counts.deprecated)/tot, - (100 * self.counts.unmarked)/tot) - }; - - try!(write!(f, -r"

Stability dashboard: crate {name}

-This dashboard summarizes the stability levels for all of the public modules of -the crate, according to the total number of items at each level in the module and -its children (percentages total for {name}): -
- stable ({}%),
- unstable ({}%),
- deprecated ({}%),
- unmarked ({}%) -
-The counts do not include methods or trait -implementations that are visible only through a re-exported type.", -stable, unstable, deprecated, unmarked, -name=self.name)); - try!(write!(f, "")); - try!(fmt_inner(f, &mut context, self)); - write!(f, "
") - } -} diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 5f4a3e74b65..c619421635d 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -56,19 +56,20 @@ use serialize::json::ToJson; use syntax::abi; use syntax::ast; use syntax::ast_util; +use syntax::attr; use rustc::util::nodemap::NodeSet; use clean; use doctree; use fold::DocFolder; -use html::format::{VisSpace, Method, UnsafetySpace, MutableSpace, Stability}; -use html::format::{ConciseStability, TyParamBounds, WhereClause, href, AbiSpace}; +use html::escape::Escape; +use html::format::{TyParamBounds, WhereClause, href, AbiSpace}; +use html::format::{VisSpace, Method, UnsafetySpace, MutableSpace}; use html::highlight; use html::item_type::ItemType; use html::layout; use html::markdown::Markdown; use html::markdown; -use stability_summary; /// A pair of name and its optional document. pub type NameDoc = (String, Option); @@ -437,11 +438,8 @@ pub fn run(mut krate: clean::Crate, try!(write_shared(&cx, &krate, &*cache, index)); let krate = try!(render_sources(&mut cx, krate)); - // Crawl the crate, building a summary of the stability levels. - let summary = stability_summary::build(&krate); - // And finally render the whole crate's documentation - cx.krate(krate, summary) + cx.krate(krate) } fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::Result { @@ -645,8 +643,7 @@ fn write_shared(cx: &Context, // going on). If they're in different crates then the crate defining // the trait will be interested in our implementation. if imp.def_id.krate == did.krate { continue } - try!(write!(&mut f, r#""{}impl{} {}{} for {}","#, - ConciseStability(&imp.stability), + try!(write!(&mut f, r#""impl{} {}{} for {}","#, imp.generics, if imp.polarity == Some(clean::ImplPolarity::Negative) { "!" } else { "" }, imp.trait_, imp.for_)); @@ -1143,38 +1140,13 @@ impl Context { /// /// This currently isn't parallelized, but it'd be pretty easy to add /// parallelization to this function. - fn krate(mut self, mut krate: clean::Crate, - stability: stability_summary::ModuleSummary) -> io::Result<()> { + fn krate(self, mut krate: clean::Crate) -> io::Result<()> { let mut item = match krate.module.take() { Some(i) => i, None => return Ok(()) }; item.name = Some(krate.name); - // render stability dashboard - try!(self.recurse(stability.name.clone(), |this| { - let json_dst = &this.dst.join("stability.json"); - let mut json_out = BufWriter::new(try!(File::create(json_dst))); - try!(write!(&mut json_out, "{}", json::as_json(&stability))); - - let mut title = stability.name.clone(); - title.push_str(" - Stability dashboard"); - let desc = format!("API stability overview for the Rust `{}` crate.", - this.layout.krate); - let page = layout::Page { - ty: "mod", - root_path: &this.root_path, - title: &title, - description: &desc, - keywords: get_basic_keywords(), - }; - let html_dst = &this.dst.join("stability.html"); - let mut html_out = BufWriter::new(try!(File::create(html_dst))); - layout::render(&mut html_out, &this.layout, &page, - &Sidebar{ cx: this, item: &item }, - &stability) - })); - // render the crate documentation let mut work = vec!((self, item)); loop { @@ -1456,21 +1428,8 @@ impl<'a> fmt::Display for Item<'a> { try!(write!(fmt, "{}", shortty(self.item), self.item.name.as_ref().unwrap())); - // Write stability level - try!(write!(fmt, "{}", Stability(&self.item.stability))); - try!(write!(fmt, "")); // in-band - // Links to out-of-band information, i.e. src and stability dashboard try!(write!(fmt, "")); - - // Write stability dashboard link - match self.item.inner { - clean::ModuleItem(ref m) if m.is_crate => { - try!(write!(fmt, "[stability] ")); - } - _ => {} - }; - try!(write!(fmt, r##" [-] [+] @@ -1554,11 +1513,11 @@ fn plain_summary_line(s: Option<&str>) -> String { } fn document(w: &mut fmt::Formatter, item: &clean::Item) -> fmt::Result { - match item.doc_value() { - Some(s) => { - try!(write!(w, "
{}
", Markdown(s))); - } - None => {} + if let Some(s) = short_stability(item, true) { + try!(write!(w, "
{}
", s)); + } + if let Some(s) = item.doc_value() { + try!(write!(w, "
{}
", Markdown(s))); } Ok(()) } @@ -1593,10 +1552,17 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context, fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: usize, idx2: usize) -> Ordering { let ty1 = shortty(i1); let ty2 = shortty(i2); - if ty1 == ty2 { - return i1.name.cmp(&i2.name); + if ty1 != ty2 { + return (reorder(ty1), idx1).cmp(&(reorder(ty2), idx2)) } - (reorder(ty1), idx1).cmp(&(reorder(ty2), idx2)) + let s1 = i1.stability.as_ref().map(|s| s.level); + let s2 = i2.stability.as_ref().map(|s| s.level); + match (s1, s2) { + (Some(attr::Unstable), Some(attr::Stable)) => return Ordering::Greater, + (Some(attr::Stable), Some(attr::Unstable)) => return Ordering::Less, + _ => {} + } + i1.name.cmp(&i2.name) } indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2)); @@ -1665,19 +1631,27 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context, _ => { if myitem.name.is_none() { continue } + let stab_docs = if let Some(s) = short_stability(myitem, false) { + format!("[{}]", s) + } else { + String::new() + }; try!(write!(w, " - - {stab}{} - {} + + {name} + + {stab_docs} {docs} + ", - *myitem.name.as_ref().unwrap(), - Markdown(&shorter(myitem.doc_value())[..]), + name = *myitem.name.as_ref().unwrap(), + stab_docs = stab_docs, + docs = Markdown(&shorter(myitem.doc_value())), class = shortty(myitem), + stab = myitem.stability_class(), href = item_path(myitem), - title = full_path(cx, myitem), - stab = ConciseStability(&myitem.stability))); + title = full_path(cx, myitem))); } } } @@ -1685,6 +1659,30 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context, write!(w, "") } +fn short_stability(item: &clean::Item, show_reason: bool) -> Option { + item.stability.as_ref().and_then(|stab| { + let reason = if show_reason && stab.reason.len() > 0 { + format!(": {}", stab.reason) + } else { + String::new() + }; + let text = if stab.deprecated_since.len() > 0 { + let since = if show_reason { + format!(" since {}", Escape(&stab.deprecated_since)) + } else { + String::new() + }; + format!("Deprecated{}{}", since, Markdown(&reason)) + } else if stab.level == attr::Unstable { + format!("Unstable{}", Markdown(&reason)) + } else { + return None + }; + Some(format!("{}", + item.stability_class(), text)) + }) +} + struct Initializer<'a>(&'a str); impl<'a> fmt::Display for Initializer<'a> { @@ -1800,10 +1798,10 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, fn trait_item(w: &mut fmt::Formatter, m: &clean::Item) -> fmt::Result { - try!(write!(w, "

{}", - shortty(m), - *m.name.as_ref().unwrap(), - ConciseStability(&m.stability))); + try!(write!(w, "

", + ty = shortty(m), + name = *m.name.as_ref().unwrap(), + stab = m.stability_class())); try!(render_method(w, m, MethodLink::Anchor)); try!(write!(w, "

")); try!(document(w, m)); @@ -1854,8 +1852,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, match cache.implementors.get(&it.def_id) { Some(implementors) => { for i in implementors { - try!(writeln!(w, "
  • {}impl{} {} for {}{}
  • ", - ConciseStability(&i.stability), + try!(writeln!(w, "
  • impl{} {} for {}{}
  • ", i.generics, i.trait_, i.for_, WhereClause(&i.generics))); } } @@ -1964,9 +1961,10 @@ fn item_struct(w: &mut fmt::Formatter, it: &clean::Item, if fields.peek().is_some() { try!(write!(w, "

    Fields

    \n")); for field in fields { - try!(write!(w, " + ")); @@ -2034,8 +2032,7 @@ fn item_enum(w: &mut fmt::Formatter, it: &clean::Item, if !e.variants.is_empty() { try!(write!(w, "

    Variants

    \n
    \ - {stab}{name}", - stab = ConciseStability(&field.stability), + try!(write!(w, "
    \ + {name}", + stab = field.stability_class(), name = field.name.as_ref().unwrap())); try!(document(w, field)); try!(write!(w, "
    ")); for variant in &e.variants { - try!(write!(w, "
    {stab}{name}", - stab = ConciseStability(&variant.stability), + try!(write!(w, "
    {name}", name = variant.name.as_ref().unwrap())); try!(document(w, variant)); match variant.inner { @@ -2200,8 +2197,7 @@ fn render_methods(w: &mut fmt::Formatter, it: &clean::Item) -> fmt::Result { fn render_impl(w: &mut fmt::Formatter, i: &Impl, link: MethodLink) -> fmt::Result { - try!(write!(w, "

    {}impl{} ", - ConciseStability(&i.stability), + try!(write!(w, "

    impl{} ", i.impl_.generics)); if let Some(clean::ImplPolarity::Negative) = i.impl_.polarity { try!(write!(w, "!")); @@ -2216,48 +2212,43 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl, link: MethodLink) } fn doctraititem(w: &mut fmt::Formatter, item: &clean::Item, - dox: bool, link: MethodLink) -> fmt::Result { + link: MethodLink) -> fmt::Result { match item.inner { clean::MethodItem(..) | clean::TyMethodItem(..) => { - try!(write!(w, "

    {}", + try!(write!(w, "

    ", *item.name.as_ref().unwrap(), - shortty(item), - ConciseStability(&item.stability))); + shortty(item))); try!(render_method(w, item, link)); try!(write!(w, "

    \n")); } clean::TypedefItem(ref tydef) => { let name = item.name.as_ref().unwrap(); - try!(write!(w, "

    {}", + try!(write!(w, "

    ", *name, - shortty(item), - ConciseStability(&item.stability))); + shortty(item))); try!(write!(w, "type {} = {}", name, tydef.type_)); try!(write!(w, "

    \n")); } clean::AssociatedTypeItem(ref bounds, ref default) => { let name = item.name.as_ref().unwrap(); - try!(write!(w, "

    {}", + try!(write!(w, "

    ", *name, - shortty(item), - ConciseStability(&item.stability))); + shortty(item))); try!(assoc_type(w, item, bounds, default)); try!(write!(w, "

    \n")); } _ => panic!("can't make docs for trait item with name {:?}", item.name) } - match item.doc_value() { - Some(s) if dox => { - try!(write!(w, "
    {}
    ", Markdown(s))); - Ok(()) - } - Some(..) | None => Ok(()) + if let MethodLink::Anchor = link { + document(w, item) + } else { + Ok(()) } } try!(write!(w, "
    ")); for trait_item in i.impl_.items.iter() { - try!(doctraititem(w, trait_item, true, link)); + try!(doctraititem(w, trait_item, link)); } fn render_default_methods(w: &mut fmt::Formatter, @@ -2271,8 +2262,7 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl, link: MethodLink) None => {} } - try!(doctraititem(w, trait_item, false, - MethodLink::GotoSource(did))); + try!(doctraititem(w, trait_item, MethodLink::GotoSource(did))); } Ok(()) } diff --git a/src/librustdoc/html/static/main.css b/src/librustdoc/html/static/main.css index 2af20ce59da..657b2c8fef8 100644 --- a/src/librustdoc/html/static/main.css +++ b/src/librustdoc/html/static/main.css @@ -245,6 +245,10 @@ nav.sub { .content .highlighted.tymethod { background-color: #c6afb3; } .content .highlighted.type { background-color: #c6afb3; } +.docblock.short p { + display: inline; +} + .docblock.short.nowrap { display: block; overflow: hidden; @@ -337,11 +341,16 @@ nav.sub { /* Shift "where ..." part of method definition down a line */ .content .method .where { display: block; } /* Bit of whitespace to indent it */ -.content .method .where::before { content: ' '; } +.content .method .where::before { content: ' '; } -.content .methods .docblock { margin-left: 40px; } +.content .methods > div { margin-left: 40px; } -.content .impl-items .docblock { margin-left: 40px; } +.content .impl-items .docblock, .content .impl-items .stability { + margin-left: 40px; +} +.content .impl-items .method, .content .impl-items .type { + margin-left: 20px; +} nav { border-bottom: 1px solid #e0e0e0; @@ -468,31 +477,28 @@ a { padding: 20px; } -.stability { - border-left: 6px solid; - padding: 3px 6px; - border-radius: 3px; +em.stab.unstable { background: #FFF5D6; border-color: #FFC600; } +em.stab.deprecated { background: #F3DFFF; border-color: #7F0087; } +em.stab { + display: inline-block; + border-width: 2px; + border-style: solid; + padding: 5px; +} +em.stab p { + display: inline; } -h1 .stability { - text-transform: lowercase; - font-weight: 400; - margin-left: 14px; - padding: 4px 10px; +.module-item .stab { + border-width: 0; + padding: 0; + background: inherit !important; } -.impl-items .stability, .methods .stability { - margin-right: 20px; +.module-item.unstable { + opacity: 0.65; } -.stability.Deprecated { border-color: #A071A8; color: #82478C; } -.stability.Experimental { border-color: #D46D6A; color: #AA3C39; } -.stability.Unstable { border-color: #D4B16A; color: #AA8439; } -.stability.Stable { border-color: #54A759; color: #2D8632; } -.stability.Frozen { border-color: #009431; color: #007726; } -.stability.Locked { border-color: #0084B6; color: #00668c; } -.stability.Unmarked { border-color: #BBBBBB; } - td.summary-column { width: 100%; } @@ -500,11 +506,6 @@ td.summary-column { .summary { padding-right: 0px; } -.summary.Deprecated { background-color: #A071A8; } -.summary.Experimental { background-color: #D46D6A; } -.summary.Unstable { background-color: #D4B16A; } -.summary.Stable { background-color: #54A759; } -.summary.Unmarked { background-color: #BBBBBB; } :target { background: #FDFFD3; } .line-numbers :target { background-color: transparent; } @@ -555,9 +556,9 @@ pre.rust { position: relative; } .collapse-toggle { font-weight: 300; position: absolute; - left: 13px; + left: -23px; color: #999; - margin-top: 2px; + top: 0; } .toggle-wrapper > .collapse-toggle { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 008da466db0..2682bbf4662 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -91,7 +91,6 @@ pub mod html { pub mod markdown; pub mod passes; pub mod plugins; -pub mod stability_summary; pub mod visit_ast; pub mod test; mod flock; diff --git a/src/librustdoc/stability_summary.rs b/src/librustdoc/stability_summary.rs deleted file mode 100644 index 3e4f6896ee6..00000000000 --- a/src/librustdoc/stability_summary.rs +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright 2014 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! This module crawls a `clean::Crate` and produces a summarization of the -//! stability levels within the crate. The summary contains the module -//! hierarchy, with item counts for every stability level per module. A parent -//! module's count includes its children's. - -use std::cmp::Ordering; -use std::ops::Add; - -use syntax::attr::{Unstable, Stable}; -use syntax::ast::Public; - -use clean::{Crate, Item, ModuleItem, Module, EnumItem, Enum}; -use clean::{ImplItem, Impl, Trait, TraitItem}; -use clean::{ExternCrateItem, ImportItem, PrimitiveItem, Stability}; - -use html::render::cache; - -#[derive(RustcEncodable, RustcDecodable, PartialEq, Eq)] -/// The counts for each stability level. -#[derive(Copy, Clone)] -pub struct Counts { - pub deprecated: u64, - pub unstable: u64, - pub stable: u64, - - /// No stability level, inherited or otherwise. - pub unmarked: u64, -} - -impl Add for Counts { - type Output = Counts; - - fn add(self, other: Counts) -> Counts { - Counts { - deprecated: self.deprecated + other.deprecated, - unstable: self.unstable + other.unstable, - stable: self.stable + other.stable, - unmarked: self.unmarked + other.unmarked, - } - } -} - -impl Counts { - fn zero() -> Counts { - Counts { - deprecated: 0, - unstable: 0, - stable: 0, - unmarked: 0, - } - } - - pub fn total(&self) -> u64 { - self.deprecated + self.unstable + self.stable + self.unmarked - } -} - -#[derive(RustcEncodable, RustcDecodable, PartialEq, Eq)] -/// A summarized module, which includes total counts and summarized children -/// modules. -pub struct ModuleSummary { - pub name: String, - pub counts: Counts, - pub submodules: Vec, -} - -impl PartialOrd for ModuleSummary { - fn partial_cmp(&self, other: &ModuleSummary) -> Option { - self.name.partial_cmp(&other.name) - } -} - -impl Ord for ModuleSummary { - fn cmp(&self, other: &ModuleSummary) -> Ordering { - self.name.cmp(&other.name) - } -} - -// is the item considered publicly visible? -fn visible(item: &Item) -> bool { - match item.inner { - ImplItem(_) => true, - _ => item.visibility == Some(Public) - } -} - -fn count_stability(stab: Option<&Stability>) -> Counts { - match stab { - None => Counts { unmarked: 1, .. Counts::zero() }, - Some(ref stab) => { - if !stab.deprecated_since.is_empty() { - return Counts { deprecated: 1, .. Counts::zero() }; - } - match stab.level { - Unstable => Counts { unstable: 1, .. Counts::zero() }, - Stable => Counts { stable: 1, .. Counts::zero() }, - } - } - } -} - -fn summarize_methods(item: &Item) -> Counts { - match cache().impls.get(&item.def_id) { - Some(v) => { - v.iter().map(|i| { - let count = count_stability(i.stability.as_ref()); - if i.impl_.trait_.is_none() { - count + i.impl_.items.iter() - .map(|ti| summarize_item(ti).0) - .fold(Counts::zero(), |acc, c| acc + c) - } else { - count - } - }).fold(Counts::zero(), |acc, c| acc + c) - }, - None => { - Counts::zero() - }, - } -} - - -// Produce the summary for an arbitrary item. If the item is a module, include a -// module summary. The counts for items with nested items (e.g. modules, traits, -// impls) include all children counts. -fn summarize_item(item: &Item) -> (Counts, Option) { - let item_counts = count_stability(item.stability.as_ref()) + summarize_methods(item); - - // Count this item's children, if any. Note that a trait impl is - // considered to have no children. - match item.inner { - // Require explicit `pub` to be visible - ImplItem(Impl { ref items, trait_: None, .. }) => { - let subcounts = items.iter().filter(|i| visible(*i)) - .map(summarize_item) - .map(|s| s.0) - .fold(Counts::zero(), |acc, x| acc + x); - (subcounts, None) - } - // `pub` automatically - EnumItem(Enum { variants: ref subitems, .. }) => { - let subcounts = subitems.iter().map(summarize_item) - .map(|s| s.0) - .fold(Counts::zero(), |acc, x| acc + x); - (item_counts + subcounts, None) - } - TraitItem(Trait { ref items, .. }) => { - let subcounts = items.iter().map(summarize_item) - .map(|s| s.0) - .fold(Counts::zero(), |acc, x| acc + x); - (item_counts + subcounts, None) - } - ModuleItem(Module { ref items, .. }) => { - let mut counts = item_counts; - let mut submodules = Vec::new(); - - for (subcounts, submodule) in items.iter().filter(|i| visible(*i)) - .map(summarize_item) { - counts = counts + subcounts; - submodule.map(|m| submodules.push(m)); - } - submodules.sort(); - - (counts, Some(ModuleSummary { - name: item.name.as_ref().map_or("".to_string(), |n| n.clone()), - counts: counts, - submodules: submodules, - })) - } - // no stability information for the following items: - ExternCrateItem(..) | ImportItem(_) | - PrimitiveItem(_) => (Counts::zero(), None), - _ => (item_counts, None) - } -} - -/// Summarizes the stability levels in a crate. -pub fn build(krate: &Crate) -> ModuleSummary { - match krate.module { - None => ModuleSummary { - name: krate.name.clone(), - counts: Counts::zero(), - submodules: Vec::new(), - }, - Some(ref item) => ModuleSummary { - name: krate.name.clone(), .. summarize_item(item).1.unwrap() - } - } -}