rust 33 lines · 6 steps

Zero-copy HTML escaping with Cow in Rust

How Cow lets escape_html avoid allocating when there's nothing to escape.

Explained by highlit
1use std::borrow::Cow;
2 
3pub fn escape_html(input: &str) -> Cow<'_, str> {
4 let needs_escape = input
5 .bytes()
6 .any(|b| matches!(b, b'&' | b'<' | b'>' | b'"' | b'\''));
7 
8 if !needs_escape {
9 return Cow::Borrowed(input);
10 }
11 
12 let mut escaped = String::with_capacity(input.len() + 16);
13 for ch in input.chars() {
14 match ch {
15 '&' => escaped.push_str("&amp;"),
16 '<' => escaped.push_str("&lt;"),
17 '>' => escaped.push_str("&gt;"),
18 '"' => escaped.push_str("&quot;"),
19 '\'' => escaped.push_str("&#x27;"),
20 other => escaped.push(other),
21 }
22 }
23 
24 Cow::Owned(escaped)
25}
26 
27pub fn render_comment(author: &str, body: &str) -> String {
28 format!(
29 "<article class=\"comment\">\n <h3>{}</h3>\n <p>{}</p>\n</article>",
30 escape_html(author),
31 escape_html(body),
32 )
33}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Cow lets a function return either a borrow or an owned value from one signature, deferring allocation until it's actually needed.
  2. 2A cheap upfront scan can spare the common case from any allocation at all.
  3. 3Pre-sizing the output buffer with with_capacity trims reallocations when you already know the growth is small.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Zero-copy HTML escaping with Cow in Rust — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code