pub(crate) const REDACTION_PLACEHOLDER: &str = "[REDACTED]";
const REDACT_SUBSTRINGS: &[&str] = &[
"password",
"passwd",
"secret",
"token",
"cookie",
"authorization",
"credential",
"api_key",
"apikey",
"private_key",
"bearer",
];
const REDACT_SUFFIXES: &[&str] = &["_cert", "_pem"];
const REDACT_EXACT: &[&str] = &["auth", "cert", "pem"];
pub(crate) fn is_redacted(field_name: &str) -> bool {
let lower = field_name.to_ascii_lowercase();
REDACT_SUBSTRINGS.iter().any(|s| lower.contains(s))
|| REDACT_SUFFIXES.iter().any(|s| lower.ends_with(s))
|| REDACT_EXACT.iter().any(|e| lower == *e)
}
pub(crate) fn is_system_sentinel(rendered: &str) -> bool {
rendered == "system" || rendered == "\"system\""
}
pub(crate) fn escape_control(value: &str) -> String {
if !value.chars().any(char::is_control) {
return value.to_owned();
}
let mut out = String::with_capacity(value.len() + 8);
for c in value.chars() {
match c {
'\n' => out.push_str("\\n"),
'\r' => out.push_str("\\r"),
'\t' => out.push_str("\\t"),
c if c.is_control() => out.push_str(&format!("\\u{{{:04x}}}", c as u32)),
c => out.push(c),
}
}
out
}