From d048cc699aae75777bb85a3dff40e29de4563d80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Romero?= Date: Wed, 30 Sep 2026 18:03:59 +0000 Subject: [PATCH] perf: escape vCard values in one buffer --- crates/flectar-mail-core/src/carddav/vcard.rs | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/crates/flectar-mail-core/src/carddav/vcard.rs b/crates/flectar-mail-core/src/carddav/vcard.rs index 69ac5d12..b24021cd 100644 --- a/crates/flectar-mail-core/src/carddav/vcard.rs +++ b/crates/flectar-mail-core/src/carddav/vcard.rs @@ -30,11 +30,24 @@ fn unescape(value: &str) -> String { } fn escape(value: &str) -> String { - value - .replace('\\', "\\\\") - .replace('\n', "\\n") - .replace(';', "\\;") - .replace(',', "\\,") + let capacity = value + .chars() + .map(|ch| match ch { + '\\' | '\n' | ';' | ',' => 2, + _ => ch.len_utf8(), + }) + .sum(); + let mut escaped = String::with_capacity(capacity); + for ch in value.chars() { + match ch { + '\\' => escaped.push_str("\\\\"), + '\n' => escaped.push_str("\\n"), + ';' => escaped.push_str("\\;"), + ',' => escaped.push_str("\\,"), + _ => escaped.push(ch), + } + } + escaped } fn split_escaped(value: &str, delimiter: char) -> Vec {