88use std:: borrow:: Cow ;
99use std:: collections:: VecDeque ;
1010use std:: fmt:: { self , Display , Write } ;
11+ use std:: iter;
1112
1213use rustc_data_structures:: fx:: FxIndexMap ;
1314use rustc_lexer:: { Cursor , FrontmatterAllowed , LiteralKind , TokenKind } ;
1415use rustc_span:: edition:: Edition ;
1516use rustc_span:: symbol:: Symbol ;
1617use rustc_span:: { BytePos , DUMMY_SP , Span } ;
1718
18- use super :: format:: { self , write_str } ;
19+ use super :: format;
1920use crate :: clean:: PrimitiveType ;
21+ use crate :: display:: Joined as _;
2022use crate :: html:: escape:: EscapeBodyText ;
2123use crate :: html:: macro_expansion:: ExpandedCode ;
2224use crate :: html:: render:: { Context , LinkFromSrc } ;
@@ -51,26 +53,26 @@ pub(crate) enum Tooltip {
5153/// Highlights `src` as an inline example, returning the HTML output.
5254pub ( crate ) fn render_example_with_highlighting (
5355 src : & str ,
54- out : & mut String ,
55- tooltip : Tooltip ,
56+ tooltip : & Tooltip ,
5657 playground_button : Option < & str > ,
5758 extra_classes : & [ String ] ,
58- ) {
59- write_header ( out, "rust-example-rendered" , None , tooltip, extra_classes) ;
60- write_code ( out, src, None , None , None ) ;
61- write_footer ( out, playground_button) ;
59+ ) -> impl Display {
60+ fmt:: from_fn ( move |f| {
61+ write_header ( "rust-example-rendered" , None , tooltip, extra_classes) . fmt ( f) ?;
62+ write_code ( f, src, None , None , None ) ;
63+ write_footer ( playground_button) . fmt ( f)
64+ } )
6265}
6366
6467fn write_header (
65- out : & mut String ,
6668 class : & str ,
6769 extra_content : Option < & str > ,
68- tooltip : Tooltip ,
70+ tooltip : & Tooltip ,
6971 extra_classes : & [ String ] ,
70- ) {
71- write_str (
72- out ,
73- format_args ! (
72+ ) -> impl Display {
73+ fmt :: from_fn ( move |f| {
74+ write ! (
75+ f ,
7476 "<div class=\" example-wrap{}\" >" ,
7577 match tooltip {
7678 Tooltip :: IgnoreAll | Tooltip :: IgnoreSome ( _) => " ignore" ,
@@ -79,58 +81,48 @@ fn write_header(
7981 Tooltip :: Edition ( _) => " edition" ,
8082 Tooltip :: None => "" ,
8183 }
82- ) ,
83- ) ;
84-
85- if tooltip != Tooltip :: None {
86- let tooltip = fmt:: from_fn ( |f| match & tooltip {
87- Tooltip :: IgnoreAll => f. write_str ( "This example is not tested" ) ,
88- Tooltip :: IgnoreSome ( platforms) => {
89- f. write_str ( "This example is not tested on " ) ?;
90- match & platforms[ ..] {
91- [ ] => unreachable ! ( ) ,
92- [ platform] => f. write_str ( platform) ?,
93- [ first, second] => write ! ( f, "{first} or {second}" ) ?,
94- [ platforms @ .., last] => {
95- for platform in platforms {
96- write ! ( f, "{platform}, " ) ?;
84+ ) ?;
85+
86+ if * tooltip != Tooltip :: None {
87+ let tooltip = fmt:: from_fn ( |f| match tooltip {
88+ Tooltip :: IgnoreAll => f. write_str ( "This example is not tested" ) ,
89+ Tooltip :: IgnoreSome ( platforms) => {
90+ f. write_str ( "This example is not tested on " ) ?;
91+ match & platforms[ ..] {
92+ [ ] => unreachable ! ( ) ,
93+ [ platform] => f. write_str ( platform) ?,
94+ [ first, second] => write ! ( f, "{first} or {second}" ) ?,
95+ [ platforms @ .., last] => {
96+ for platform in platforms {
97+ write ! ( f, "{platform}, " ) ?;
98+ }
99+ write ! ( f, "or {last}" ) ?;
97100 }
98- write ! ( f, "or {last}" ) ?;
99101 }
102+ Ok ( ( ) )
100103 }
101- Ok ( ( ) )
102- }
103- Tooltip :: CompileFail => f. write_str ( "This example deliberately fails to compile" ) ,
104- Tooltip :: ShouldPanic => f. write_str ( "This example panics" ) ,
105- Tooltip :: Edition ( edition) => write ! ( f, "This example runs with edition {edition}" ) ,
106- Tooltip :: None => unreachable ! ( ) ,
104+ Tooltip :: CompileFail => f. write_str ( "This example deliberately fails to compile" ) ,
105+ Tooltip :: ShouldPanic => f. write_str ( "This example panics" ) ,
106+ Tooltip :: Edition ( edition) => write ! ( f, "This example runs with edition {edition}" ) ,
107+ Tooltip :: None => unreachable ! ( ) ,
108+ } ) ;
109+
110+ write ! ( f, "<a href=\" #\" class=\" tooltip\" title=\" {tooltip}\" >ⓘ</a>" ) ?;
111+ }
112+
113+ if let Some ( extra) = extra_content {
114+ f. write_str ( extra) ?;
115+ }
116+
117+ let classes = fmt:: from_fn ( |f| {
118+ iter:: once ( "rust" )
119+ . chain ( Some ( class) . filter ( |class| !class. is_empty ( ) ) )
120+ . chain ( extra_classes. iter ( ) . map ( String :: as_str) )
121+ . joined ( " " , f)
107122 } ) ;
108- write_str ( out, format_args ! ( "<a href=\" #\" class=\" tooltip\" title=\" {tooltip}\" >ⓘ</a>" ) ) ;
109- }
110123
111- if let Some ( extra) = extra_content {
112- out. push_str ( extra) ;
113- }
114- if class. is_empty ( ) {
115- write_str (
116- out,
117- format_args ! (
118- "<pre class=\" rust{}{}\" >" ,
119- if extra_classes. is_empty( ) { "" } else { " " } ,
120- extra_classes. join( " " )
121- ) ,
122- ) ;
123- } else {
124- write_str (
125- out,
126- format_args ! (
127- "<pre class=\" rust {class}{}{}\" >" ,
128- if extra_classes. is_empty( ) { "" } else { " " } ,
129- extra_classes. join( " " )
130- ) ,
131- ) ;
132- }
133- write_str ( out, format_args ! ( "<code>" ) ) ;
124+ write ! ( f, "<pre class=\" {classes}\" ><code>" )
125+ } )
134126}
135127
136128/// Check if two `Class` can be merged together. In the following rules, "unclassified" means `None`
@@ -577,8 +569,8 @@ pub(super) fn write_code(
577569 } ) ;
578570}
579571
580- fn write_footer ( out : & mut String , playground_button : Option < & str > ) {
581- write_str ( out , format_args ! ( "</code></pre>{}</div>" , playground_button. unwrap_or_default( ) ) ) ;
572+ fn write_footer ( playground_button : Option < & str > ) -> impl Display {
573+ fmt :: from_fn ( move |f| write ! ( f , "</code></pre>{}</div>" , playground_button. unwrap_or_default( ) ) )
582574}
583575
584576/// How a span of text is classified. Mostly corresponds to token kinds.
0 commit comments