workflow_html/
escape.rs

1use lazy_static::lazy_static;
2use regex::Regex;
3use std::borrow::Cow;
4
5pub fn escape_attr<'a, S: Into<Cow<'a, str>>>(input: S) -> Cow<'a, str> {
6    lazy_static! {
7        static ref REGEX: Regex = Regex::new("[<>&\"]").unwrap();
8    }
9    let input = input.into();
10    let first = REGEX.find(&input);
11    if let Some(m) = first {
12        let first = m.start();
13        let len = input.len();
14        let mut output: Vec<u8> = Vec::with_capacity(len + len / 2);
15        output.extend_from_slice(input[0..first].as_bytes());
16        let rest = input[first..].bytes();
17        for c in rest {
18            match c {
19                b'<' => output.extend_from_slice(b"&lt;"),
20                b'>' => output.extend_from_slice(b"&gt;"),
21                b'&' => output.extend_from_slice(b"&amp;"),
22                b'"' => output.extend_from_slice(b"&quot;"),
23                _ => output.push(c),
24            }
25        }
26        Cow::Owned(unsafe { String::from_utf8_unchecked(output) })
27    } else {
28        input
29    }
30}
31pub fn escape_html<'a, S: Into<Cow<'a, str>>>(input: S) -> Cow<'a, str> {
32    lazy_static! {
33        static ref REGEX: Regex = Regex::new("[<>&]").unwrap();
34    }
35    let input = input.into();
36    let first = REGEX.find(&input);
37    if let Some(m) = first {
38        let first = m.start();
39        let len = input.len();
40        let mut output: Vec<u8> = Vec::with_capacity(len + len / 2);
41        output.extend_from_slice(input[0..first].as_bytes());
42        let rest = input[first..].bytes();
43        for c in rest {
44            match c {
45                b'<' => output.extend_from_slice(b"&lt;"),
46                b'>' => output.extend_from_slice(b"&gt;"),
47                b'&' => output.extend_from_slice(b"&amp;"),
48                _ => output.push(c),
49            }
50        }
51        Cow::Owned(unsafe { String::from_utf8_unchecked(output) })
52    } else {
53        input
54    }
55}