diff --git a/crates/teloxide/src/utils/html.rs b/crates/teloxide/src/utils/html.rs index 37f6f034..5fa2ee91 100644 --- a/crates/teloxide/src/utils/html.rs +++ b/crates/teloxide/src/utils/html.rs @@ -101,7 +101,15 @@ pub fn code_inline(s: &str) -> String { #[must_use = "This function returns a new string, rather than mutating the argument, so calling it \ without using its output does nothing useful"] pub fn escape(s: &str) -> String { - s.replace('&', "&").replace('<', "<").replace('>', ">") + s.chars().fold(String::with_capacity(s.len()), |mut s, c| { + match c { + '&' => s.push_str("&"), + '<' => s.push_str("<"), + '>' => s.push_str(">"), + c => s.push(c), + } + s + }) } #[must_use = "This function returns a new string, rather than mutating the argument, so calling it \ diff --git a/crates/teloxide/src/utils/markdown.rs b/crates/teloxide/src/utils/markdown.rs index 4c0fa475..ad6eb26c 100644 --- a/crates/teloxide/src/utils/markdown.rs +++ b/crates/teloxide/src/utils/markdown.rs @@ -109,24 +109,16 @@ pub fn code_inline(s: &str) -> String { #[must_use = "This function returns a new string, rather than mutating the argument, so calling it \ without using its output does nothing useful"] pub fn escape(s: &str) -> String { - s.replace('_', r"\_") - .replace('*', r"\*") - .replace('[', r"\[") - .replace(']', r"\]") - .replace('(', r"\(") - .replace(')', r"\)") - .replace('~', r"\~") - .replace('`', r"\`") - .replace('>', r"\>") - .replace('#', r"\#") - .replace('+', r"\+") - .replace('-', r"\-") - .replace('=', r"\=") - .replace('|', r"\|") - .replace('{', r"\{") - .replace('}', r"\}") - .replace('.', r"\.") - .replace('!', r"\!") + const CHARS: [char; 18] = + ['_', '*', '[', ']', '(', ')', '~', '`', '>', '#', '+', '-', '=', '|', '{', '}', '.', '!']; + + s.chars().fold(String::with_capacity(s.len()), |mut s, c| { + if CHARS.contains(&c) { + s.push('\\'); + } + s.push(c); + s + }) } /// Escapes all markdown special characters specific for the inline link URL @@ -134,7 +126,13 @@ pub fn escape(s: &str) -> String { #[must_use = "This function returns a new string, rather than mutating the argument, so calling it \ without using its output does nothing useful"] pub fn escape_link_url(s: &str) -> String { - s.replace('`', r"\`").replace(')', r"\)") + s.chars().fold(String::with_capacity(s.len()), |mut s, c| { + if ['`', ')'].contains(&c) { + s.push('\\'); + } + s.push(c); + s + }) } /// Escapes all markdown special characters specific for the code block (``` and @@ -142,7 +140,13 @@ pub fn escape_link_url(s: &str) -> String { #[must_use = "This function returns a new string, rather than mutating the argument, so calling it \ without using its output does nothing useful"] pub fn escape_code(s: &str) -> String { - s.replace('\\', r"\\").replace('`', r"\`") + s.chars().fold(String::with_capacity(s.len()), |mut s, c| { + if ['`', '\\'].contains(&c) { + s.push('\\'); + } + s.push(c); + s + }) } #[must_use = "This function returns a new string, rather than mutating the argument, so calling it \