@@ -37,6 +37,7 @@ mod span_map;
3737mod type_layout;
3838mod write_shared;
3939
40+ use std:: borrow:: Cow ;
4041use std:: collections:: VecDeque ;
4142use std:: fmt:: { self , Display as _, Write } ;
4243use std:: iter:: Peekable ;
@@ -96,6 +97,19 @@ pub(crate) enum AssocItemRender<'a> {
9697 DerefFor { trait_ : & ' a clean:: Path , type_ : & ' a clean:: Type , deref_mut_ : bool } ,
9798}
9899
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+
99113/// For different handling of associated items from the Deref target of a type rather than the type
100114/// itself.
101115#[ derive( Copy , Clone , PartialEq ) ]
@@ -1208,7 +1222,7 @@ impl<'a> AssocItemLink<'a> {
12081222}
12091223
12101224pub fn write_section_heading (
1211- title : & str ,
1225+ title : impl fmt :: Display ,
12121226 id : & str ,
12131227 extra_class : Option < & str > ,
12141228 extra : impl fmt:: Display ,
@@ -1228,7 +1242,7 @@ pub fn write_section_heading(
12281242 } )
12291243}
12301244
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 {
12321246 write_section_heading ( title, id, None , "" )
12331247}
12341248
@@ -1304,42 +1318,41 @@ fn render_assoc_items_inner(
13041318 let Some ( v) = cache. impls . get ( & it) else { return } ;
13051319 let ( non_trait, traits) : ( Vec < _ > , _ ) = v. iter ( ) . partition ( |i| i. inner_impl ( ) . trait_ . is_none ( ) ) ;
13061320 if !non_trait. is_empty ( ) {
1307- let mut close_tags = <Vec < & str > >:: with_capacity ( 1 ) ;
1308- let mut tmp_buf = String :: new ( ) ;
1309- let ( render_mode, id, class_html) = match what {
1310- AssocItemRender :: All => {
1311- write_str (
1312- & mut tmp_buf,
1313- format_args ! (
1314- "{}" ,
1315- write_impl_section_heading( "Implementations" , "implementations" )
1316- ) ,
1317- ) ;
1318- ( RenderMode :: Normal , "implementations-list" . to_owned ( ) , "" )
1319- }
1320- AssocItemRender :: DerefFor { trait_, type_, deref_mut_ } => {
1321+ let render_mode = what. render_mode ( ) ;
1322+ let class_html = what
1323+ . class ( )
1324+ . map ( |class| fmt:: from_fn ( move |f| write ! ( f, r#" class="{class}""# ) ) )
1325+ . maybe_display ( ) ;
1326+ let ( section_heading, id) = match what {
1327+ AssocItemRender :: All => (
1328+ Either :: Left ( write_impl_section_heading ( "Implementations" , "implementations" ) ) ,
1329+ Cow :: Borrowed ( "implementations-list" ) ,
1330+ ) ,
1331+ AssocItemRender :: DerefFor { trait_, type_, .. } => {
13211332 let id =
13221333 cx. derive_id ( small_url_encode ( format ! ( "deref-methods-{:#}" , type_. print( cx) ) ) ) ;
13231334 let derived_id = cx. derive_id ( & id) ;
1324- close_tags. push ( "</details>" ) ;
1325- write_str (
1326- & mut tmp_buf,
1327- format_args ! (
1328- "<details class=\" toggle big-toggle\" open><summary>{}</summary>" ,
1329- write_impl_section_heading(
1330- & format!(
1331- "<span>Methods from {trait_}<Target = {type_}></span>" ,
1332- trait_ = trait_. print( cx) ,
1333- type_ = type_. print( cx) ,
1334- ) ,
1335- & id,
1336- )
1337- ) ,
1338- ) ;
13391335 if let Some ( def_id) = type_. def_id ( cx. cache ( ) ) {
1340- cx. deref_id_map . borrow_mut ( ) . insert ( def_id, id) ;
1336+ cx. deref_id_map . borrow_mut ( ) . insert ( def_id, id. clone ( ) ) ;
13411337 }
1342- ( RenderMode :: ForDeref { mut_ : deref_mut_ } , derived_id, r#" class="impl-items""# )
1338+ (
1339+ Either :: Right ( fmt:: from_fn ( move |f| {
1340+ write ! (
1341+ f,
1342+ "<details class=\" toggle big-toggle\" open><summary>{}</summary>" ,
1343+ write_impl_section_heading(
1344+ fmt:: from_fn( |f| write!(
1345+ f,
1346+ "<span>Methods from {trait_}<Target = {type_}></span>" ,
1347+ trait_ = trait_. print( cx) ,
1348+ type_ = type_. print( cx) ,
1349+ ) ) ,
1350+ & id,
1351+ )
1352+ )
1353+ } ) ) ,
1354+ Cow :: Owned ( derived_id) ,
1355+ )
13431356 }
13441357 } ;
13451358 let mut impls_buf = String :: new ( ) ;
@@ -1367,10 +1380,14 @@ fn render_assoc_items_inner(
13671380 ) ;
13681381 }
13691382 if !impls_buf. is_empty ( ) {
1370- write ! ( w, "{tmp_buf}<div id=\" {id}\" {class_html}>{impls_buf}</div>" ) . unwrap ( ) ;
1371- for tag in close_tags. into_iter ( ) . rev ( ) {
1372- w. write_str ( tag) . unwrap ( ) ;
1373- }
1383+ write ! (
1384+ w,
1385+ "{section_heading}<div id=\" {id}\" {class_html}>{impls_buf}</div>{}" ,
1386+ matches!( what, AssocItemRender :: DerefFor { .. } )
1387+ . then_some( "</details>" )
1388+ . maybe_display( ) ,
1389+ )
1390+ . unwrap ( ) ;
13741391 }
13751392 }
13761393
0 commit comments