Skip to content

Commit 14824c5

Browse files
committed
Only allocate maximum once in small_url_encode
1 parent e8f90b1 commit 14824c5

File tree

1 file changed

+35
-17
lines changed
  • src/librustdoc/html/render

1 file changed

+35
-17
lines changed

src/librustdoc/html/render/mod.rs

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3510,7 +3510,7 @@ fn render_assoc_items(
35103510
RenderMode::Normal
35113511
}
35123512
AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => {
3513-
let id = cx.derive_id(small_url_encode(&format!(
3513+
let id = cx.derive_id(small_url_encode(format!(
35143514
"deref-methods-{:#}",
35153515
type_.print(cx.cache())
35163516
)));
@@ -3761,7 +3761,7 @@ fn render_impl(
37613761
if is_on_foreign_type {
37623762
get_id_for_impl_on_foreign_type(&i.inner_impl().for_, t, cx.cache())
37633763
} else {
3764-
format!("impl-{}", small_url_encode(&format!("{:#}", t.print(cx.cache()))))
3764+
format!("impl-{}", small_url_encode(format!("{:#}", t.print(cx.cache()))))
37653765
}
37663766
}
37673767
None => "impl".to_string(),
@@ -4264,19 +4264,37 @@ fn get_methods(
42644264
}
42654265

42664266
// The point is to url encode any potential character from a type with genericity.
4267-
fn small_url_encode(s: &str) -> String {
4268-
s.replace("<", "%3C")
4269-
.replace(">", "%3E")
4270-
.replace(" ", "%20")
4271-
.replace("?", "%3F")
4272-
.replace("'", "%27")
4273-
.replace("&", "%26")
4274-
.replace(",", "%2C")
4275-
.replace(":", "%3A")
4276-
.replace(";", "%3B")
4277-
.replace("[", "%5B")
4278-
.replace("]", "%5D")
4279-
.replace("\"", "%22")
4267+
fn small_url_encode(s: String) -> String {
4268+
let mut st = String::new();
4269+
let mut last_match = 0;
4270+
for (idx, c) in s.char_indices() {
4271+
let escaped = match c {
4272+
'<' => "%3C",
4273+
'>' => "%3E",
4274+
' ' => "%20",
4275+
'?' => "%3F",
4276+
'\'' => "%27",
4277+
'&' => "%26",
4278+
',' => "%2C",
4279+
':' => "%3A",
4280+
';' => "%3B",
4281+
'[' => "%5B",
4282+
']' => "%5D",
4283+
'"' => "%22",
4284+
_ => continue,
4285+
};
4286+
4287+
st += &s[last_match..idx];
4288+
st += escaped;
4289+
last_match = idx + c.len_utf8();
4290+
}
4291+
4292+
if last_match != 0 {
4293+
st += &s[last_match..];
4294+
st
4295+
} else {
4296+
s
4297+
}
42804298
}
42814299

42824300
fn sidebar_assoc_items(cx: &Context<'_>, it: &clean::Item) -> String {
@@ -4321,7 +4339,7 @@ fn sidebar_assoc_items(cx: &Context<'_>, it: &clean::Item) -> String {
43214339
if let Some(ref i) = it.inner_impl().trait_ {
43224340
let i_display = format!("{:#}", i.print(cx.cache()));
43234341
let out = Escape(&i_display);
4324-
let encoded = small_url_encode(&format!("{:#}", i.print(cx.cache())));
4342+
let encoded = small_url_encode(format!("{:#}", i.print(cx.cache())));
43254343
let generated = format!(
43264344
"<a href=\"#impl-{}\">{}{}</a>",
43274345
encoded,
@@ -4477,7 +4495,7 @@ fn get_id_for_impl_on_foreign_type(
44774495
trait_: &clean::Type,
44784496
cache: &Cache,
44794497
) -> String {
4480-
small_url_encode(&format!("impl-{:#}-for-{:#}", trait_.print(cache), for_.print(cache)))
4498+
small_url_encode(format!("impl-{:#}-for-{:#}", trait_.print(cache), for_.print(cache)))
44814499
}
44824500

44834501
fn extract_for_impl_name(item: &clean::Item, cache: &Cache) -> Option<(String, String)> {

0 commit comments

Comments
 (0)