8
8
use std:: borrow:: Cow ;
9
9
use std:: collections:: VecDeque ;
10
10
use std:: fmt:: { self , Display , Write } ;
11
+ use std:: iter;
11
12
12
13
use rustc_data_structures:: fx:: FxIndexMap ;
13
14
use rustc_lexer:: { Cursor , FrontmatterAllowed , LiteralKind , TokenKind } ;
14
15
use rustc_span:: edition:: Edition ;
15
16
use rustc_span:: symbol:: Symbol ;
16
17
use rustc_span:: { BytePos , DUMMY_SP , Span } ;
17
18
18
- use super :: format:: { self , write_str } ;
19
+ use super :: format;
19
20
use crate :: clean:: PrimitiveType ;
21
+ use crate :: display:: Joined as _;
20
22
use crate :: html:: escape:: EscapeBodyText ;
21
23
use crate :: html:: macro_expansion:: ExpandedCode ;
22
24
use crate :: html:: render:: { Context , LinkFromSrc } ;
@@ -51,26 +53,26 @@ pub(crate) enum Tooltip {
51
53
/// Highlights `src` as an inline example, returning the HTML output.
52
54
pub ( crate ) fn render_example_with_highlighting (
53
55
src : & str ,
54
- out : & mut String ,
55
- tooltip : Tooltip ,
56
+ tooltip : & Tooltip ,
56
57
playground_button : Option < & str > ,
57
58
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
+ } )
62
65
}
63
66
64
67
fn write_header (
65
- out : & mut String ,
66
68
class : & str ,
67
69
extra_content : Option < & str > ,
68
- tooltip : Tooltip ,
70
+ tooltip : & Tooltip ,
69
71
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 ,
74
76
"<div class=\" example-wrap{}\" >" ,
75
77
match tooltip {
76
78
Tooltip :: IgnoreAll | Tooltip :: IgnoreSome ( _) => " ignore" ,
@@ -79,58 +81,48 @@ fn write_header(
79
81
Tooltip :: Edition ( _) => " edition" ,
80
82
Tooltip :: None => "" ,
81
83
}
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}" ) ?;
97
100
}
98
- write ! ( f, "or {last}" ) ?;
99
101
}
102
+ Ok ( ( ) )
100
103
}
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)
107
122
} ) ;
108
- write_str ( out, format_args ! ( "<a href=\" #\" class=\" tooltip\" title=\" {tooltip}\" >ⓘ</a>" ) ) ;
109
- }
110
123
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
+ } )
134
126
}
135
127
136
128
/// Check if two `Class` can be merged together. In the following rules, "unclassified" means `None`
@@ -577,8 +569,8 @@ pub(super) fn write_code(
577
569
} ) ;
578
570
}
579
571
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( ) ) )
582
574
}
583
575
584
576
/// How a span of text is classified. Mostly corresponds to token kinds.
0 commit comments