@@ -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
@@ -1305,20 +1319,17 @@ fn render_assoc_items_inner(
13051319 let ( mut non_trait, traits) : ( Vec < _ > , _ ) =
13061320 v. iter ( ) . partition ( |i| i. inner_impl ( ) . trait_ . is_none ( ) ) ;
13071321 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_, .. } => {
13221333 let id =
13231334 cx. derive_id ( small_url_encode ( format ! ( "deref-methods-{:#}" , type_. print( cx) ) ) ) ;
13241335 // the `impls.get` above only looks at the outermost type,
@@ -1332,25 +1343,27 @@ fn render_assoc_items_inner(
13321343 type_. is_doc_subtype_of ( & impl_. inner_impl ( ) . for_ , & cx. shared . cache )
13331344 } ) ;
13341345 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- ) ;
13501346 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 ( ) ) ;
13521348 }
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+ )
13541367 }
13551368 } ;
13561369 let mut impls_buf = String :: new ( ) ;
@@ -1378,10 +1391,14 @@ fn render_assoc_items_inner(
13781391 ) ;
13791392 }
13801393 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 ( ) ;
13851402 }
13861403 }
13871404
0 commit comments