text-fx 0.4.0

A collection of text processing utilities for Rust.
Documentation
pub enum EscapeStyle {
    Trigraph,
    XML,
}

pub fn xml_escape_str(s: &str) -> String {
    let mut o = String::new();
    for c in s.chars() {
        match c {
            '&' => o.push_str("&"),
            '<' => o.push_str("&lt;"),
            '>' => o.push_str("&gt;"),
            '"' => o.push_str("&quot;"),
            _ => o.push(c),
        }
    }
    o
}

fn escape_trigraphs(p: &str) -> String {
    let data = p.as_bytes();
    let mut s = Vec::new();
    let mut i = 0;
    let len = data.len();
    while i < len {
        if i + 2 < len && data[i] == b'?' && data[i + 1] == b'?' {
            match data[i + 2] {
                b'!' | b'\'' | b'(' | b')' | b'-' | b'/' | b'<' | b'=' | b'>' => {
                    i += 2;
                    s.push(b'?');
                    s.push(b'"');
                    s.push(b'"');
                    s.push(b'?');
                    continue;
                }
                _ => {}
            }
        }
        s.push(data[i]);
        i += 1;
    }
    String::from_utf8(s).unwrap()
}

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

    #[test]
    fn test_escape() {
        let s = "∃¬∩∪∀";
        let p = escape_trigraphs(s);
        assert_eq!(s, p);
        let s = r#"\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!"#;
        let expected = r#"\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081?""?!"#;
        let p = escape_trigraphs(s);
        assert_eq!(expected, p);
    }
}