@@ -11,8 +11,8 @@ use rustc_span::symbol::{kw, sym, Symbol};
11
11
12
12
use super :: {
13
13
collect_paths_for_type, document, ensure_trailing_slash, item_ty_to_strs, notable_traits_decl,
14
- render_assoc_item, render_assoc_items, render_attributes , render_impl ,
15
- render_stability_since_raw, write_srclink, AssocItemLink , Context ,
14
+ render_assoc_item, render_assoc_items, render_attributes_in_code , render_attributes_in_pre ,
15
+ render_impl , render_stability_since_raw, write_srclink, AssocItemLink , Context ,
16
16
} ;
17
17
use crate :: clean:: { self , GetDefId } ;
18
18
use crate :: formats:: cache:: Cache ;
@@ -131,6 +131,26 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer)
131
131
}
132
132
}
133
133
134
+ /// For large structs, enums, unions, etc, determine whether to hide their fields
135
+ fn should_hide_fields ( n_fields : usize ) -> bool {
136
+ n_fields > 12
137
+ }
138
+
139
+ fn toggle_open ( w : & mut Buffer , text : & str ) {
140
+ write ! (
141
+ w,
142
+ "<details class=\" rustdoc-toggle type-contents-toggle\" >\
143
+ <summary class=\" hideme\" >\
144
+ <span>Show {}</span>\
145
+ </summary>",
146
+ text
147
+ ) ;
148
+ }
149
+
150
+ fn toggle_close ( w : & mut Buffer ) {
151
+ w. write_str ( "</details>" ) ;
152
+ }
153
+
134
154
fn item_module ( w : & mut Buffer , cx : & Context < ' _ > , item : & clean:: Item , items : & [ clean:: Item ] ) {
135
155
document ( w, cx, item, None ) ;
136
156
@@ -377,7 +397,7 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::
377
397
)
378
398
. len ( ) ;
379
399
w. write_str ( "<pre class=\" rust fn\" >" ) ;
380
- render_attributes ( w, it, false ) ;
400
+ render_attributes_in_pre ( w, it, "" ) ;
381
401
write ! (
382
402
w,
383
403
"{vis}{constness}{asyncness}{unsafety}{abi}fn \
@@ -406,7 +426,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
406
426
// Output the trait definition
407
427
wrap_into_docblock ( w, |w| {
408
428
w. write_str ( "<pre class=\" rust trait\" >" ) ;
409
- render_attributes ( w, it, true ) ;
429
+ render_attributes_in_pre ( w, it, "" ) ;
410
430
write ! (
411
431
w,
412
432
"{}{}{}trait {}{}{}" ,
@@ -429,17 +449,36 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
429
449
} else {
430
450
// FIXME: we should be using a derived_id for the Anchors here
431
451
w. write_str ( "{\n " ) ;
452
+ let mut toggle = false ;
453
+
454
+ // If there are too many associated types, hide _everything_
455
+ if should_hide_fields ( types. len ( ) ) {
456
+ toggle = true ;
457
+ toggle_open ( w, "associated items" ) ;
458
+ }
432
459
for t in & types {
433
460
render_assoc_item ( w, t, AssocItemLink :: Anchor ( None ) , ItemType :: Trait , cx) ;
434
461
w. write_str ( ";\n " ) ;
435
462
}
463
+ // If there are too many associated constants, hide everything after them
464
+ // We also do this if the types + consts is large because otherwise we could
465
+ // render a bunch of types and _then_ a bunch of consts just because both were
466
+ // _just_ under the limit
467
+ if !toggle && should_hide_fields ( types. len ( ) + consts. len ( ) ) {
468
+ toggle = true ;
469
+ toggle_open ( w, "associated constants and methods" ) ;
470
+ }
436
471
if !types. is_empty ( ) && !consts. is_empty ( ) {
437
472
w. write_str ( "\n " ) ;
438
473
}
439
474
for t in & consts {
440
475
render_assoc_item ( w, t, AssocItemLink :: Anchor ( None ) , ItemType :: Trait , cx) ;
441
476
w. write_str ( ";\n " ) ;
442
477
}
478
+ if !toggle && should_hide_fields ( required. len ( ) + provided. len ( ) ) {
479
+ toggle = true ;
480
+ toggle_open ( w, "methods" ) ;
481
+ }
443
482
if !consts. is_empty ( ) && !required. is_empty ( ) {
444
483
w. write_str ( "\n " ) ;
445
484
}
@@ -470,6 +509,9 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
470
509
w. write_str ( "<div class=\" item-spacer\" ></div>" ) ;
471
510
}
472
511
}
512
+ if toggle {
513
+ toggle_close ( w) ;
514
+ }
473
515
w. write_str ( "}" ) ;
474
516
}
475
517
w. write_str ( "</pre>" )
@@ -693,7 +735,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
693
735
694
736
fn item_trait_alias ( w : & mut Buffer , cx : & Context < ' _ > , it : & clean:: Item , t : & clean:: TraitAlias ) {
695
737
w. write_str ( "<pre class=\" rust trait-alias\" >" ) ;
696
- render_attributes ( w, it, false ) ;
738
+ render_attributes_in_pre ( w, it, "" ) ;
697
739
write ! (
698
740
w,
699
741
"trait {}{}{} = {};</pre>" ,
@@ -714,7 +756,7 @@ fn item_trait_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clea
714
756
715
757
fn item_opaque_ty ( w : & mut Buffer , cx : & Context < ' _ > , it : & clean:: Item , t : & clean:: OpaqueTy ) {
716
758
w. write_str ( "<pre class=\" rust opaque\" >" ) ;
717
- render_attributes ( w, it, false ) ;
759
+ render_attributes_in_pre ( w, it, "" ) ;
718
760
write ! (
719
761
w,
720
762
"type {}{}{where_clause} = impl {bounds};</pre>" ,
@@ -735,7 +777,7 @@ fn item_opaque_ty(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean:
735
777
736
778
fn item_typedef ( w : & mut Buffer , cx : & Context < ' _ > , it : & clean:: Item , t : & clean:: Typedef ) {
737
779
w. write_str ( "<pre class=\" rust typedef\" >" ) ;
738
- render_attributes ( w, it, false ) ;
780
+ render_attributes_in_pre ( w, it, "" ) ;
739
781
write ! (
740
782
w,
741
783
"type {}{}{where_clause} = {type_};</pre>" ,
@@ -757,7 +799,7 @@ fn item_typedef(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::T
757
799
fn item_union ( w : & mut Buffer , cx : & Context < ' _ > , it : & clean:: Item , s : & clean:: Union ) {
758
800
wrap_into_docblock ( w, |w| {
759
801
w. write_str ( "<pre class=\" rust union\" >" ) ;
760
- render_attributes ( w, it, true ) ;
802
+ render_attributes_in_pre ( w, it, "" ) ;
761
803
render_union ( w, it, Some ( & s. generics ) , & s. fields , "" , true , cx) ;
762
804
w. write_str ( "</pre>" )
763
805
} ) ;
@@ -803,7 +845,7 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni
803
845
fn item_enum ( w : & mut Buffer , cx : & Context < ' _ > , it : & clean:: Item , e : & clean:: Enum ) {
804
846
wrap_into_docblock ( w, |w| {
805
847
w. write_str ( "<pre class=\" rust enum\" >" ) ;
806
- render_attributes ( w, it, true ) ;
848
+ render_attributes_in_pre ( w, it, "" ) ;
807
849
write ! (
808
850
w,
809
851
"{}enum {}{}{}" ,
@@ -816,6 +858,10 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
816
858
w. write_str ( " {}" ) ;
817
859
} else {
818
860
w. write_str ( " {\n " ) ;
861
+ let toggle = should_hide_fields ( e. variants . len ( ) ) ;
862
+ if toggle {
863
+ toggle_open ( w, "variants" ) ;
864
+ }
819
865
for v in & e. variants {
820
866
w. write_str ( " " ) ;
821
867
let name = v. name . as_ref ( ) . unwrap ( ) ;
@@ -844,6 +890,9 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
844
890
if e. variants_stripped {
845
891
w. write_str ( " // some variants omitted\n " ) ;
846
892
}
893
+ if toggle {
894
+ toggle_close ( w) ;
895
+ }
847
896
w. write_str ( "}" ) ;
848
897
}
849
898
w. write_str ( "</pre>" )
@@ -976,7 +1025,7 @@ fn item_primitive(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) {
976
1025
977
1026
fn item_constant ( w : & mut Buffer , cx : & Context < ' _ > , it : & clean:: Item , c : & clean:: Constant ) {
978
1027
w. write_str ( "<pre class=\" rust const\" >" ) ;
979
- render_attributes ( w, it, false ) ;
1028
+ render_attributes_in_code ( w, it) ;
980
1029
981
1030
write ! (
982
1031
w,
@@ -1015,7 +1064,7 @@ fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean::
1015
1064
fn item_struct ( w : & mut Buffer , cx : & Context < ' _ > , it : & clean:: Item , s : & clean:: Struct ) {
1016
1065
wrap_into_docblock ( w, |w| {
1017
1066
w. write_str ( "<pre class=\" rust struct\" >" ) ;
1018
- render_attributes ( w, it, true ) ;
1067
+ render_attributes_in_code ( w, it) ;
1019
1068
render_struct ( w, it, Some ( & s. generics ) , s. struct_type , & s. fields , "" , true , cx) ;
1020
1069
w. write_str ( "</pre>" )
1021
1070
} ) ;
@@ -1064,7 +1113,7 @@ fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St
1064
1113
1065
1114
fn item_static ( w : & mut Buffer , cx : & Context < ' _ > , it : & clean:: Item , s : & clean:: Static ) {
1066
1115
w. write_str ( "<pre class=\" rust static\" >" ) ;
1067
- render_attributes ( w, it, false ) ;
1116
+ render_attributes_in_code ( w, it) ;
1068
1117
write ! (
1069
1118
w,
1070
1119
"{vis}static {mutability}{name}: {typ}</pre>" ,
@@ -1078,7 +1127,7 @@ fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St
1078
1127
1079
1128
fn item_foreign_type ( w : & mut Buffer , cx : & Context < ' _ > , it : & clean:: Item ) {
1080
1129
w. write_str ( "<pre class=\" rust foreigntype\" >extern {\n " ) ;
1081
- render_attributes ( w, it, false ) ;
1130
+ render_attributes_in_code ( w, it) ;
1082
1131
write ! (
1083
1132
w,
1084
1133
" {}type {};\n }}</pre>" ,
@@ -1171,7 +1220,7 @@ fn wrap_into_docblock<F>(w: &mut Buffer, f: F)
1171
1220
where
1172
1221
F : FnOnce ( & mut Buffer ) ,
1173
1222
{
1174
- w. write_str ( "<div class=\" docblock type-decl hidden-by-usual-hider \" >" ) ;
1223
+ w. write_str ( "<div class=\" docblock type-decl\" >" ) ;
1175
1224
f ( w) ;
1176
1225
w. write_str ( "</div>" )
1177
1226
}
@@ -1261,6 +1310,13 @@ fn render_union(
1261
1310
}
1262
1311
1263
1312
write ! ( w, " {{\n {}" , tab) ;
1313
+ let count_fields =
1314
+ fields. iter ( ) . filter ( |f| matches ! ( * f. kind, clean:: StructFieldItem ( ..) ) ) . count ( ) ;
1315
+ let toggle = should_hide_fields ( count_fields) ;
1316
+ if toggle {
1317
+ toggle_open ( w, "fields" ) ;
1318
+ }
1319
+
1264
1320
for field in fields {
1265
1321
if let clean:: StructFieldItem ( ref ty) = * field. kind {
1266
1322
write ! (
@@ -1277,6 +1333,9 @@ fn render_union(
1277
1333
if it. has_stripped_fields ( ) . unwrap ( ) {
1278
1334
write ! ( w, " // some fields omitted\n {}" , tab) ;
1279
1335
}
1336
+ if toggle {
1337
+ toggle_close ( w) ;
1338
+ }
1280
1339
w. write_str ( "}" ) ;
1281
1340
}
1282
1341
@@ -1305,8 +1364,14 @@ fn render_struct(
1305
1364
if let Some ( g) = g {
1306
1365
write ! ( w, "{}" , print_where_clause( g, cx. cache( ) , cx. tcx( ) , 0 , true ) , )
1307
1366
}
1308
- let mut has_visible_fields = false ;
1309
1367
w. write_str ( " {" ) ;
1368
+ let count_fields =
1369
+ fields. iter ( ) . filter ( |f| matches ! ( * f. kind, clean:: StructFieldItem ( ..) ) ) . count ( ) ;
1370
+ let has_visible_fields = count_fields > 0 ;
1371
+ let toggle = should_hide_fields ( count_fields) ;
1372
+ if toggle {
1373
+ toggle_open ( w, "fields" ) ;
1374
+ }
1310
1375
for field in fields {
1311
1376
if let clean:: StructFieldItem ( ref ty) = * field. kind {
1312
1377
write ! (
@@ -1317,7 +1382,6 @@ fn render_struct(
1317
1382
field. name. as_ref( ) . unwrap( ) ,
1318
1383
ty. print( cx. cache( ) , cx. tcx( ) ) ,
1319
1384
) ;
1320
- has_visible_fields = true ;
1321
1385
}
1322
1386
}
1323
1387
@@ -1331,6 +1395,9 @@ fn render_struct(
1331
1395
// `{ /* fields omitted */ }` to save space.
1332
1396
write ! ( w, " /* fields omitted */ " ) ;
1333
1397
}
1398
+ if toggle {
1399
+ toggle_close ( w) ;
1400
+ }
1334
1401
w. write_str ( "}" ) ;
1335
1402
}
1336
1403
CtorKind :: Fn => {
0 commit comments