diff --git a/.Jules/bolt.md b/.Jules/bolt.md new file mode 100644 index 0000000..7f34568 --- /dev/null +++ b/.Jules/bolt.md @@ -0,0 +1,3 @@ +## 2026-07-18 - Zero-Cost Abstractions in String Manipulation +**Learning:** Chaining `format!()` macros and `.collect::>` on short configuration strings in hot loops causes massive heap allocation overhead. `Vec` allocates `4 * N` bytes plus structural overhead just to look at the first and last element of a string. +**Action:** When working with strings where capacity can be pre-calculated (like concatenating known lengths) or where parsing bounds is needed (like finding the first and last char), always use `String::with_capacity()` or iterator mapping (`chars()`) directly. This reduces allocations to a single, sized heap structure, making the hot path substantially faster. diff --git a/src/utils/secrets/mod.rs b/src/utils/secrets/mod.rs index c3ef485..6cb344d 100644 --- a/src/utils/secrets/mod.rs +++ b/src/utils/secrets/mod.rs @@ -121,21 +121,33 @@ fn get_object_identifier(map: &serde_json::Map) -> Option /// Helper to format environment variable names fn format_env_var_name(prefix: &str, key: &str) -> String { - let env_var_name = if prefix.is_empty() { - format!("KEYCLOAK_{}", key) - } else { - format!("KEYCLOAK_{}_{}", prefix, key) - }; - env_var_name - .chars() - .map(|c| { - if c.is_alphanumeric() { + // Pre-calculate capacity to avoid reallocations: "KEYCLOAK_" + prefix + "_" + key + let capacity = + "KEYCLOAK_".len() + prefix.len() + if prefix.is_empty() { 0 } else { 1 } + key.len(); + let mut out = String::with_capacity(capacity); + + out.push_str("KEYCLOAK_"); + + if !prefix.is_empty() { + for c in prefix.chars() { + out.push(if c.is_alphanumeric() { c.to_ascii_uppercase() } else { '_' - } - }) - .collect() + }); + } + out.push('_'); + } + + for c in key.chars() { + out.push(if c.is_alphanumeric() { + c.to_ascii_uppercase() + } else { + '_' + }); + } + + out } /// Recursively extract secrets and replace them with ${ENV_VAR} @@ -228,13 +240,27 @@ fn obfuscate_string(s: &str) -> String { return s.to_string(); } - let chars: Vec = s.chars().collect(); - if chars.len() <= 3 { + let mut chars = s.chars(); + // String is not empty, so next() will return Some + let first = chars.next().unwrap(); + + let mut count = 1; + let mut last = first; + + for c in chars { + last = c; + count += 1; + } + + if count <= 3 { return "***".to_string(); } - let first = chars[0]; - let last = chars[chars.len() - 1]; - format!("{}***{}", first, last) + + let mut out = String::with_capacity(first.len_utf8() + 3 + last.len_utf8()); + out.push(first); + out.push_str("***"); + out.push(last); + out } /// Recursively obfuscate known secret fields