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
//! escaping provides functions for the Server Query escaping.
//!
//! # Example
//! ```
//! use sqlib::escaping::{escape, unescape};
//!
//! let unescaped = "hello world/|\\".to_string();
//! let escaped = "hello\\sworld\\/\\p\\\\".to_string();
//!
//! let escaped_test = escape(&unescaped);
//! let unescaped_test = unescape(&escaped);
//!
//! assert_eq!(escaped_test, escaped);
//! assert_eq!(unescaped_test, unescaped);
//! ```

const ESCAPE_CHARS: [(char, &str); 11] = [
    ('\\', r"\\"),
    (' ', r"\s"),
    ('/', r"\/"),
    ('|', r"\p"),
    (7 as char, r"\a"),
    (8 as char, r"\b"),
    (9 as char, r"\t"),
    (10 as char, r"\n"),
    (11 as char, r"\v"),
    (12 as char, r"\f"),
    (13 as char, r"\r"),
];

/// escapes all chars described in the server query manual
///
/// # Example
/// ```
/// use sqlib::escaping::escape;
///
/// let unescaped = "hello world/|\\".to_string();
/// let escaped = "hello\\sworld\\/\\p\\\\".to_string();
///
/// let s = escape(&unescaped);
///
/// assert_eq!(s, escaped);
/// ```
pub fn escape(s: &str) -> String {
    let mut new_string = s.to_string();
    for &(from, to) in &ESCAPE_CHARS {
        new_string = new_string.replace(from, to);
    }
    new_string
}

/// unescapes all chars described in the server query manual
///
/// # Example
/// ```
/// use sqlib::escaping::unescape;
///
/// let unescaped = "hello world/|\\".to_string();
/// let escaped = "hello\\sworld\\/\\p\\\\".to_string();
///
/// let s = unescape(&escaped);
///
/// assert_eq!(s, unescaped);
/// ```
pub fn unescape(s: &str) -> String {
    let mut new_string = s.to_string();
    for &(to, from) in &ESCAPE_CHARS {
        new_string = new_string.replace(from, &to.to_string());
    }
    new_string
}