Skip to content

Commit 58c7505

Browse files
committed
Make render_example_with_highlighting return an impl fmt::Display
1 parent 4056082 commit 58c7505

File tree

2 files changed

+62
-71
lines changed

2 files changed

+62
-71
lines changed

src/librustdoc/html/highlight.rs

Lines changed: 54 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,17 @@
88
use std::borrow::Cow;
99
use std::collections::VecDeque;
1010
use std::fmt::{self, Display, Write};
11+
use std::iter;
1112

1213
use rustc_data_structures::fx::FxIndexMap;
1314
use rustc_lexer::{Cursor, FrontmatterAllowed, LiteralKind, TokenKind};
1415
use rustc_span::edition::Edition;
1516
use rustc_span::symbol::Symbol;
1617
use rustc_span::{BytePos, DUMMY_SP, Span};
1718

18-
use super::format::{self, write_str};
19+
use super::format;
1920
use crate::clean::PrimitiveType;
21+
use crate::display::Joined as _;
2022
use crate::html::escape::EscapeBodyText;
2123
use crate::html::macro_expansion::ExpandedCode;
2224
use crate::html::render::{Context, LinkFromSrc};
@@ -51,26 +53,26 @@ pub(crate) enum Tooltip {
5153
/// Highlights `src` as an inline example, returning the HTML output.
5254
pub(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

6467
fn 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.

src/librustdoc/html/markdown.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -337,15 +337,14 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
337337

338338
// insert newline to clearly separate it from the
339339
// previous block so we can shorten the html output
340-
let mut s = String::new();
341-
s.push('\n');
342-
343-
highlight::render_example_with_highlighting(
344-
&text,
345-
&mut s,
346-
tooltip,
347-
playground_button.as_deref(),
348-
&added_classes,
340+
let s = format!(
341+
"\n{}",
342+
highlight::render_example_with_highlighting(
343+
&text,
344+
&tooltip,
345+
playground_button.as_deref(),
346+
&added_classes,
347+
)
349348
);
350349
Some(Event::Html(s.into()))
351350
}

0 commit comments

Comments
 (0)