@@ -40,6 +40,7 @@ mod span_map;
40
40
mod type_layout;
41
41
mod write_shared;
42
42
43
+ use std:: borrow:: Cow ;
43
44
use std:: collections:: VecDeque ;
44
45
use std:: fmt:: { self , Display as _, Write } ;
45
46
use std:: iter:: Peekable ;
@@ -99,6 +100,19 @@ enum AssocItemRender<'a> {
99
100
DerefFor { trait_ : & ' a clean:: Path , type_ : & ' a clean:: Type , deref_mut_ : bool } ,
100
101
}
101
102
103
+ impl AssocItemRender < ' _ > {
104
+ fn render_mode ( & self ) -> RenderMode {
105
+ match self {
106
+ Self :: All => RenderMode :: Normal ,
107
+ & Self :: DerefFor { deref_mut_, .. } => RenderMode :: ForDeref { mut_ : deref_mut_ } ,
108
+ }
109
+ }
110
+
111
+ fn class ( & self ) -> Option < & ' static str > {
112
+ if let Self :: DerefFor { .. } = self { Some ( "impl-items" ) } else { None }
113
+ }
114
+ }
115
+
102
116
/// For different handling of associated items from the Deref target of a type rather than the type
103
117
/// itself.
104
118
#[ derive( Copy , Clone , PartialEq ) ]
@@ -1211,7 +1225,7 @@ impl<'a> AssocItemLink<'a> {
1211
1225
}
1212
1226
1213
1227
fn write_section_heading (
1214
- title : & str ,
1228
+ title : impl fmt :: Display ,
1215
1229
id : & str ,
1216
1230
extra_class : Option < & str > ,
1217
1231
extra : impl fmt:: Display ,
@@ -1231,7 +1245,7 @@ fn write_section_heading(
1231
1245
} )
1232
1246
}
1233
1247
1234
- fn write_impl_section_heading ( title : & str , id : & str ) -> impl fmt:: Display {
1248
+ fn write_impl_section_heading ( title : impl fmt :: Display , id : & str ) -> impl fmt:: Display {
1235
1249
write_section_heading ( title, id, None , "" )
1236
1250
}
1237
1251
@@ -1308,20 +1322,17 @@ fn render_assoc_items_inner(
1308
1322
let ( mut non_trait, traits) : ( Vec < _ > , _ ) =
1309
1323
v. iter ( ) . partition ( |i| i. inner_impl ( ) . trait_ . is_none ( ) ) ;
1310
1324
if !non_trait. is_empty ( ) {
1311
- let mut close_tags = <Vec < & str > >:: with_capacity ( 1 ) ;
1312
- let mut tmp_buf = String :: new ( ) ;
1313
- let ( render_mode, id, class_html) = match what {
1314
- AssocItemRender :: All => {
1315
- write_str (
1316
- & mut tmp_buf,
1317
- format_args ! (
1318
- "{}" ,
1319
- write_impl_section_heading( "Implementations" , "implementations" )
1320
- ) ,
1321
- ) ;
1322
- ( RenderMode :: Normal , "implementations-list" . to_owned ( ) , "" )
1323
- }
1324
- AssocItemRender :: DerefFor { trait_, type_, deref_mut_ } => {
1325
+ let render_mode = what. render_mode ( ) ;
1326
+ let class_html = what
1327
+ . class ( )
1328
+ . map ( |class| fmt:: from_fn ( move |f| write ! ( f, r#" class="{class}""# ) ) )
1329
+ . maybe_display ( ) ;
1330
+ let ( section_heading, id) = match what {
1331
+ AssocItemRender :: All => (
1332
+ Either :: Left ( write_impl_section_heading ( "Implementations" , "implementations" ) ) ,
1333
+ Cow :: Borrowed ( "implementations-list" ) ,
1334
+ ) ,
1335
+ AssocItemRender :: DerefFor { trait_, type_, .. } => {
1325
1336
let id =
1326
1337
cx. derive_id ( small_url_encode ( format ! ( "deref-methods-{:#}" , type_. print( cx) ) ) ) ;
1327
1338
// the `impls.get` above only looks at the outermost type,
@@ -1335,25 +1346,27 @@ fn render_assoc_items_inner(
1335
1346
type_. is_doc_subtype_of ( & impl_. inner_impl ( ) . for_ , & cx. shared . cache )
1336
1347
} ) ;
1337
1348
let derived_id = cx. derive_id ( & id) ;
1338
- close_tags. push ( "</details>" ) ;
1339
- write_str (
1340
- & mut tmp_buf,
1341
- format_args ! (
1342
- "<details class=\" toggle big-toggle\" open><summary>{}</summary>" ,
1343
- write_impl_section_heading(
1344
- & format!(
1345
- "<span>Methods from {trait_}<Target = {type_}></span>" ,
1346
- trait_ = trait_. print( cx) ,
1347
- type_ = type_. print( cx) ,
1348
- ) ,
1349
- & id,
1350
- )
1351
- ) ,
1352
- ) ;
1353
1349
if let Some ( def_id) = type_. def_id ( cx. cache ( ) ) {
1354
- cx. deref_id_map . borrow_mut ( ) . insert ( def_id, id) ;
1350
+ cx. deref_id_map . borrow_mut ( ) . insert ( def_id, id. clone ( ) ) ;
1355
1351
}
1356
- ( RenderMode :: ForDeref { mut_ : deref_mut_ } , derived_id, r#" class="impl-items""# )
1352
+ (
1353
+ Either :: Right ( fmt:: from_fn ( move |f| {
1354
+ write ! (
1355
+ f,
1356
+ "<details class=\" toggle big-toggle\" open><summary>{}</summary>" ,
1357
+ write_impl_section_heading(
1358
+ fmt:: from_fn( |f| write!(
1359
+ f,
1360
+ "<span>Methods from {trait_}<Target = {type_}></span>" ,
1361
+ trait_ = trait_. print( cx) ,
1362
+ type_ = type_. print( cx) ,
1363
+ ) ) ,
1364
+ & id,
1365
+ )
1366
+ )
1367
+ } ) ) ,
1368
+ Cow :: Owned ( derived_id) ,
1369
+ )
1357
1370
}
1358
1371
} ;
1359
1372
let mut impls_buf = String :: new ( ) ;
@@ -1381,10 +1394,14 @@ fn render_assoc_items_inner(
1381
1394
) ;
1382
1395
}
1383
1396
if !impls_buf. is_empty ( ) {
1384
- write ! ( w, "{tmp_buf}<div id=\" {id}\" {class_html}>{impls_buf}</div>" ) . unwrap ( ) ;
1385
- for tag in close_tags. into_iter ( ) . rev ( ) {
1386
- w. write_str ( tag) . unwrap ( ) ;
1387
- }
1397
+ write ! (
1398
+ w,
1399
+ "{section_heading}<div id=\" {id}\" {class_html}>{impls_buf}</div>{}" ,
1400
+ matches!( what, AssocItemRender :: DerefFor { .. } )
1401
+ . then_some( "</details>" )
1402
+ . maybe_display( ) ,
1403
+ )
1404
+ . unwrap ( ) ;
1388
1405
}
1389
1406
}
1390
1407
0 commit comments