repotoire 0.8.3

Graph-powered code analysis CLI. 110 detectors for security, architecture, bus factor, and code quality.
Documentation
//! Shared XML/HTML attribute-and-text escape helper.
//!
//! HTML and XML/SVG reporters previously each defined a near-identical
//! 5-replacement function (`html_escape` and `xml_escape`). The only
//! difference was the apostrophe entity: HTML used `'`, XML used
//! `'`. Both are valid in HTML5 and XML 1.0, so we standardize on
//! the numeric reference (`'`) which is also valid for older XML
//! parsers and avoids an entity-vs-numeric round-trip.
//!
//! Use this for any reporter that emits angle-bracket or attribute-quoted
//! output. The function is intentionally not generic over `Cow<str>`
//! because all current callers immediately concatenate the result into a
//! `String`, so allocation is unavoidable downstream regardless.

/// Escape `&`, `<`, `>`, `"`, and `'` for safe inclusion in XML/HTML
/// element text or double-quoted attribute values.
pub fn escape_xml(s: &str) -> String {
    s.replace('&', "&amp;")
        .replace('<', "&lt;")
        .replace('>', "&gt;")
        .replace('"', "&quot;")
        .replace('\'', "&#39;")
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_escapes_all_five_special_chars() {
        assert_eq!(
            escape_xml(r#"<a href="x" b='y'> & </a>"#),
            "&lt;a href=&quot;x&quot; b=&#39;y&#39;&gt; &amp; &lt;/a&gt;"
        );
    }

    #[test]
    fn test_amp_first_to_avoid_double_escape() {
        // If `&` were replaced after `<`, then `<` -> `&lt;` -> `&amp;lt;`.
        // Verify the order is correct.
        assert_eq!(escape_xml("<&>"), "&lt;&amp;&gt;");
    }

    #[test]
    fn test_passthrough_for_safe_chars() {
        assert_eq!(escape_xml("hello world 123"), "hello world 123");
    }

    #[test]
    fn test_empty_string() {
        assert_eq!(escape_xml(""), "");
    }
}