git-slop 0.16.4

A deterministic repository token-defragmenter for humans and AI agents.
Documentation
pub(crate) fn visible_controls(value: &str) -> String {
    let mut rendered = String::with_capacity(value.len());
    for character in value.chars() {
        match character {
            '\n' => rendered.push_str("\\n"),
            '\r' => rendered.push_str("\\r"),
            '\t' => rendered.push_str("\\t"),
            control if control.is_control() => {
                rendered.push_str(&format!("\\u{{{:x}}}", control as u32));
            }
            printable => rendered.push(printable),
        }
    }
    rendered
}

pub(crate) fn markdown_escape(value: &str) -> String {
    visible_controls(value)
        .replace('\\', "\\\\")
        .replace('|', "\\|")
        .replace('[', "\\[")
        .replace(']', "\\]")
        .replace('<', "\\<")
        .replace('>', "\\>")
        .replace('`', "\\`")
}

pub(crate) fn inline_code(value: &str) -> String {
    let value = visible_controls(value);
    let mut longest_run = 0usize;
    let mut current_run = 0usize;
    for character in value.chars() {
        if character == '`' {
            current_run += 1;
            longest_run = longest_run.max(current_run);
        } else {
            current_run = 0;
        }
    }
    if longest_run == 0 {
        return format!("`{value}`");
    }
    let fence = "`".repeat(longest_run.saturating_add(1));
    format!("{fence} {value} {fence}")
}

pub(crate) fn github_property_escape(value: &str) -> String {
    value
        .replace('%', "%25")
        .replace('\r', "%0D")
        .replace('\n', "%0A")
        .replace(':', "%3A")
        .replace(',', "%2C")
}

pub(crate) fn github_message_escape(value: &str) -> String {
    value
        .replace('%', "%25")
        .replace('\r', "%0D")
        .replace('\n', "%0A")
}

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

    #[test]
    fn controls_are_visible_without_adding_output_lines() {
        assert_eq!(
            visible_controls("a\n\r\tb\u{1b}[31m"),
            "a\\n\\r\\tb\\u{1b}[31m"
        );
    }

    #[test]
    fn github_command_fields_escape_delimiters_and_line_breaks() {
        assert_eq!(
            github_property_escape("a,b:c%\r\n::warning::x"),
            "a%2Cb%3Ac%25%0D%0A%3A%3Awarning%3A%3Ax"
        );
        assert_eq!(
            github_message_escape("message%\r\n::error::x"),
            "message%25%0D%0A::error::x"
        );
    }

    #[test]
    fn markdown_and_inline_code_handle_controls_and_backtick_runs() {
        assert_eq!(markdown_escape("a|`b\n"), "a\\|\\`b\\\\n");
        assert_eq!(inline_code("a``b\n"), "``` a``b\\n ```");
    }
}