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
//! Minimal JSON string quoting, so the proof of concept needs no crates.
/// The JSON string literal for `value`, quotes included.
pub fn quote(value: &str) -> String {
let mut out = String::with_capacity(value.len() + 2);
out.push('"');
for ch in value.chars() {
match ch {
'"' => out.push_str("\\\""),
'\\' => out.push_str("\\\\"),
'\n' => out.push_str("\\n"),
'\r' => out.push_str("\\r"),
'\t' => out.push_str("\\t"),
c if c < ' ' => out.push_str(&format!("\\u{:04x}", c as u32)),
c => out.push(c),
}
}
out.push('"');
out
}
/// `Some` as its JSON literal, `None` as `null`.
pub fn option(value: Option<&str>) -> String {
value.map(quote).unwrap_or_else(|| "null".to_string())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn quotes() {
assert_eq!(quote("a"), "\"a\"");
assert_eq!(quote("a\"b\\c\n"), "\"a\\\"b\\\\c\\n\"");
assert_eq!(option(None), "null");
assert_eq!(option(Some("x")), "\"x\"");
}
}