about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEric Huss <eric@huss.org>2021-07-21 10:12:27 -0700
committerGitHub <noreply@github.com>2021-07-21 10:12:27 -0700
commit7a19fbad67b33bdb8bb0764cbfa7655657c6b197 (patch)
tree03412de423a7f3f2949cd032b2429a745f6e0b33
parenta3e1259c4db320af14a24041dc04db5a78073508 (diff)
parent2b518acc6f9da564d3024e46746ac85b47abdaa2 (diff)
downloadrust-7a19fbad67b33bdb8bb0764cbfa7655657c6b197.tar.gz
rust-7a19fbad67b33bdb8bb0764cbfa7655657c6b197.zip
Rollup merge of #87024 - weihanglo:issue-85494, r=Manishearth
rustdoc: show count of item contents when hidden

Resolves #85494
-rw-r--r--src/librustdoc/html/render/print_item.rs46
-rw-r--r--src/test/rustdoc/toggle-item-contents.rs45
2 files changed, 72 insertions, 19 deletions
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index f7073a8751f..552958d5e40 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -1,6 +1,7 @@
 use clean::AttributesExt;
 
 use std::cmp::Ordering;
+use std::fmt;
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
@@ -155,7 +156,7 @@ fn should_hide_fields(n_fields: usize) -> bool {
     n_fields > 12
 }
 
-fn toggle_open(w: &mut Buffer, text: &str) {
+fn toggle_open(w: &mut Buffer, text: impl fmt::Display) {
     write!(
         w,
         "<details class=\"rustdoc-toggle type-contents-toggle\">\
@@ -481,6 +482,9 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
     let consts = t.items.iter().filter(|m| m.is_associated_const()).collect::<Vec<_>>();
     let required = t.items.iter().filter(|m| m.is_ty_method()).collect::<Vec<_>>();
     let provided = t.items.iter().filter(|m| m.is_method()).collect::<Vec<_>>();
+    let count_types = types.len();
+    let count_consts = consts.len();
+    let count_methods = required.len() + provided.len();
 
     // Output the trait definition
     wrap_into_docblock(w, |w| {
@@ -511,9 +515,12 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
             let mut toggle = false;
 
             // If there are too many associated types, hide _everything_
-            if should_hide_fields(types.len()) {
+            if should_hide_fields(count_types) {
                 toggle = true;
-                toggle_open(w, "associated items");
+                toggle_open(
+                    w,
+                    format_args!("{} associated items", count_types + count_consts + count_methods),
+                );
             }
             for t in &types {
                 render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx);
@@ -523,9 +530,18 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
             // We also do this if the types + consts is large because otherwise we could
             // render a bunch of types and _then_ a bunch of consts just because both were
             // _just_ under the limit
-            if !toggle && should_hide_fields(types.len() + consts.len()) {
+            if !toggle && should_hide_fields(count_types + count_consts) {
                 toggle = true;
-                toggle_open(w, "associated constants and methods");
+                toggle_open(
+                    w,
+                    format_args!(
+                        "{} associated constant{} and {} method{}",
+                        count_consts,
+                        pluralize(count_consts),
+                        count_methods,
+                        pluralize(count_methods),
+                    ),
+                );
             }
             if !types.is_empty() && !consts.is_empty() {
                 w.write_str("\n");
@@ -534,9 +550,9 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
                 render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx);
                 w.write_str(";\n");
             }
-            if !toggle && should_hide_fields(required.len() + provided.len()) {
+            if !toggle && should_hide_fields(count_methods) {
                 toggle = true;
-                toggle_open(w, "methods");
+                toggle_open(w, format_args!("{} methods", count_methods));
             }
             if !consts.is_empty() && !required.is_empty() {
                 w.write_str("\n");
@@ -933,9 +949,10 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
             w.write_str(" {}");
         } else {
             w.write_str(" {\n");
-            let toggle = should_hide_fields(e.variants.len());
+            let count_variants = e.variants.len();
+            let toggle = should_hide_fields(count_variants);
             if toggle {
-                toggle_open(w, "variants");
+                toggle_open(w, format_args!("{} variants", count_variants));
             }
             for v in &e.variants {
                 w.write_str("    ");
@@ -1012,7 +1029,8 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
 
             use crate::clean::Variant;
             if let clean::VariantItem(Variant::Struct(ref s)) = *variant.kind {
-                toggle_open(w, "fields");
+                let count_fields = s.fields.len();
+                toggle_open(w, format_args!("{} field{}", count_fields, pluralize(count_fields)));
                 let variant_id = cx.derive_id(format!(
                     "{}.{}.fields",
                     ItemType::Variant,
@@ -1385,7 +1403,7 @@ fn render_union(
         fields.iter().filter(|f| matches!(*f.kind, clean::StructFieldItem(..))).count();
     let toggle = should_hide_fields(count_fields);
     if toggle {
-        toggle_open(w, "fields");
+        toggle_open(w, format_args!("{} fields", count_fields));
     }
 
     for field in fields {
@@ -1441,7 +1459,7 @@ fn render_struct(
             let has_visible_fields = count_fields > 0;
             let toggle = should_hide_fields(count_fields);
             if toggle {
-                toggle_open(w, "fields");
+                toggle_open(w, format_args!("{} fields", count_fields));
             }
             for field in fields {
                 if let clean::StructFieldItem(ref ty) = *field.kind {
@@ -1618,3 +1636,7 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) {
 
     writeln!(w, "</div>");
 }
+
+fn pluralize(count: usize) -> &'static str {
+    if count > 1 { "s" } else { "" }
+}
diff --git a/src/test/rustdoc/toggle-item-contents.rs b/src/test/rustdoc/toggle-item-contents.rs
index 6e3c0b4c681..167858b6065 100644
--- a/src/test/rustdoc/toggle-item-contents.rs
+++ b/src/test/rustdoc/toggle-item-contents.rs
@@ -9,7 +9,7 @@ pub struct PubStruct {
 
 // @has 'toggle_item_contents/struct.BigPubStruct.html'
 // @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show fields'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 13 fields'
 pub struct BigPubStruct {
     pub a: usize,
     pub b: usize,
@@ -28,7 +28,7 @@ pub struct BigPubStruct {
 
 // @has 'toggle_item_contents/union.BigUnion.html'
 // @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show fields'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 13 fields'
 pub union BigUnion {
     pub a: usize,
     pub b: usize,
@@ -63,7 +63,7 @@ pub struct PrivStruct {
 
 // @has 'toggle_item_contents/enum.Enum.html'
 // @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show fields'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 2 fields'
 pub enum Enum {
     A, B, C,
     D {
@@ -72,9 +72,19 @@ pub enum Enum {
     }
 }
 
+// @has 'toggle_item_contents/enum.EnumStructVariant.html'
+// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 1 field'
+pub enum EnumStructVariant {
+    A, B, C,
+    D {
+        a: u8,
+    }
+}
+
 // @has 'toggle_item_contents/enum.LargeEnum.html'
 // @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show variants'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 13 variants'
 pub enum LargeEnum {
     A, B, C, D, E, F(u8), G, H, I, J, K, L, M
 }
@@ -90,7 +100,7 @@ pub trait Trait {
 
 // @has 'toggle_item_contents/trait.GinormousTrait.html'
 // @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show associated items'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 16 associated items'
 pub trait GinormousTrait {
     type A;
     type B;
@@ -113,7 +123,7 @@ pub trait GinormousTrait {
 
 // @has 'toggle_item_contents/trait.HugeTrait.html'
 // @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show associated constants and methods'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 12 associated constants and 2 methods'
 pub trait HugeTrait {
     type A;
     const M: usize = 1;
@@ -133,9 +143,30 @@ pub trait HugeTrait {
     fn bar();
 }
 
+// @has 'toggle_item_contents/trait.GiganticTrait.html'
+// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 1 associated constant and 1 method'
+pub trait GiganticTrait {
+    type A;
+    type B;
+    type C;
+    type D;
+    type E;
+    type F;
+    type G;
+    type H;
+    type I;
+    type J;
+    type K;
+    type L;
+    const M: usize = 1;
+    #[must_use]
+    fn foo();
+}
+
 // @has 'toggle_item_contents/trait.BigTrait.html'
 // @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show methods'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 14 methods'
 pub trait BigTrait {
     type A;
     #[must_use]