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