1pub fn quote_identifier(name: &str) -> String {
10 let mut out = String::with_capacity(name.len() + 2);
11 out.push('"');
12 for c in name.chars() {
13 if c == '"' {
14 out.push('"');
15 }
16 out.push(c);
17 }
18 out.push('"');
19 out
20}
21
22pub fn quote_literal(value: &str) -> String {
29 let mut out = String::with_capacity(value.len() + 2);
30 out.push('\'');
31 for c in value.chars() {
32 if c == '\'' {
33 out.push('\'');
34 }
35 out.push(c);
36 }
37 out.push('\'');
38 out
39}
40
41pub fn format_value(opt: Option<&str>) -> String {
44 match opt {
45 None => "NULL".to_owned(),
46 Some(v) => quote_literal(v),
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53
54 #[test]
55 fn quote_identifier_simple() {
56 assert_eq!(quote_identifier("col"), r#""col""#);
57 }
58
59 #[test]
60 fn quote_identifier_with_quotes() {
61 assert_eq!(quote_identifier(r#"a"b"#), r#""a""b""#);
62 }
63
64 #[test]
65 fn quote_literal_simple() {
66 assert_eq!(quote_literal("hello"), "'hello'");
67 }
68
69 #[test]
70 fn quote_literal_with_quotes() {
71 assert_eq!(quote_literal("it's"), "'it''s'");
72 }
73
74 #[test]
75 fn format_value_none() {
76 assert_eq!(format_value(None), "NULL");
77 }
78
79 #[test]
80 fn format_value_some() {
81 assert_eq!(format_value(Some("hello")), "'hello'");
82 }
83
84 #[test]
85 fn format_value_some_with_quotes() {
86 assert_eq!(format_value(Some("it's")), "'it''s'");
87 }
88}