forked from Boscop/web-view
-
Notifications
You must be signed in to change notification settings - Fork 0
/
escape.rs
81 lines (68 loc) · 2.2 KB
/
escape.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
use std::fmt::{self, Write};
/// Escape a string to pass it into JavaScript.
///
/// # Example
///
/// ```rust,no_run
/// # use web_view::WebView;
/// # use std::mem;
/// #
/// # let mut view: WebView<()> = unsafe { mem::uninitialized() };
/// #
/// let string = "Hello, world!";
///
/// // Calls the function callback with "Hello, world!" as its parameter.
///
/// view.eval(&format!("callback({});", web_view::escape(string)));
/// ```
pub fn escape(string: &str) -> Escaper {
Escaper(string)
}
// "All code points may appear literally in a string literal except for the
// closing quote code points, U+005C (REVERSE SOLIDUS), U+000D (CARRIAGE
// RETURN), U+2028 (LINE SEPARATOR), U+2029 (PARAGRAPH SEPARATOR), and U+000A
// (LINE FEED)." - ES6 Specification
pub struct Escaper<'a>(&'a str);
const SPECIAL: &[char] = &[
'\n', // U+000A (LINE FEED)
'\r', // U+000D (CARRIAGE RETURN)
'\'', // U+0027 (APOSTROPHE)
'\\', // U+005C (REVERSE SOLIDUS)
'\u{2028}', // U+2028 (LINE SEPARATOR)
'\u{2029}', // U+2029 (PARAGRAPH SEPARATOR)
];
impl<'a> fmt::Display for Escaper<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let &Escaper(mut string) = self;
f.write_char('\'')?;
while !string.is_empty() {
if let Some(i) = string.find(SPECIAL) {
if i > 0 {
f.write_str(&string[..i])?;
}
let mut chars = string[i..].chars();
f.write_str(match chars.next().unwrap() {
'\n' => "\\n",
'\r' => "\\r",
'\'' => "\\'",
'\\' => "\\\\",
'\u{2028}' => "\\u2028",
'\u{2029}' => "\\u2029",
_ => unreachable!(),
})?;
string = chars.as_str();
} else {
f.write_str(string)?;
break;
}
}
f.write_char('\'')?;
Ok(())
}
}
#[test]
fn test() {
let plain = "ABC \n\r' abc \\ \u{2028} \u{2029}123";
let escaped = escape(plain).to_string();
assert!(escaped == "'ABC \\n\\r\\' abc \\\\ \\u2028 \\u2029123'");
}