@@ -40,6 +40,7 @@ mod span_map;
4040mod type_layout;
4141mod write_shared;
4242
43+ use std:: borrow:: Cow ;
4344use std:: collections:: VecDeque ;
4445use std:: fmt:: { self , Display as _, Write } ;
4546use std:: iter:: Peekable ;
@@ -99,6 +100,19 @@ enum AssocItemRender<'a> {
99100 DerefFor { trait_ : & ' a clean:: Path , type_ : & ' a clean:: Type , deref_mut_ : bool } ,
100101}
101102
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+
102116/// For different handling of associated items from the Deref target of a type rather than the type
103117/// itself.
104118#[ derive( Copy , Clone , PartialEq ) ]
@@ -1211,7 +1225,7 @@ impl<'a> AssocItemLink<'a> {
12111225}
12121226
12131227fn write_section_heading (
1214- title : & str ,
1228+ title : impl fmt :: Display ,
12151229 id : & str ,
12161230 extra_class : Option < & str > ,
12171231 extra : impl fmt:: Display ,
@@ -1231,7 +1245,7 @@ fn write_section_heading(
12311245 } )
12321246}
12331247
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 {
12351249 write_section_heading ( title, id, None , "" )
12361250}
12371251
@@ -1308,20 +1322,17 @@ fn render_assoc_items_inner(
13081322 let ( mut non_trait, traits) : ( Vec < _ > , _ ) =
13091323 v. iter ( ) . partition ( |i| i. inner_impl ( ) . trait_ . is_none ( ) ) ;
13101324 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_, .. } => {
13251336 let id =
13261337 cx. derive_id ( small_url_encode ( format ! ( "deref-methods-{:#}" , type_. print( cx) ) ) ) ;
13271338 // the `impls.get` above only looks at the outermost type,
@@ -1335,25 +1346,27 @@ fn render_assoc_items_inner(
13351346 type_. is_doc_subtype_of ( & impl_. inner_impl ( ) . for_ , & cx. shared . cache )
13361347 } ) ;
13371348 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- ) ;
13531349 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 ( ) ) ;
13551351 }
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+ )
13571370 }
13581371 } ;
13591372 let mut impls_buf = String :: new ( ) ;
@@ -1381,10 +1394,14 @@ fn render_assoc_items_inner(
13811394 ) ;
13821395 }
13831396 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 ( ) ;
13881405 }
13891406 }
13901407
0 commit comments