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
#[macro_export]
macro_rules! strip_ws_json {
    ($input: expr) => {
        $crate::ws::strip_whitespace($input, &[("\"", "\"")], &["\\\\", "\\\""])
    }
}

#[macro_export]
macro_rules! json_eq {
    ($a: expr, $b: expr) => {
        strip_ws_json!($a.as_ref()) == strip_ws_json!($b.as_ref())
    }
}

pub fn strip_whitespace(input: &str, quotes: &[(&str, &str)], ignored: &[&str]) -> String {
    let mut out = String::with_capacity(input.len());

    let mut inp = input.chars();
    let mut quote: Option<&(&str, &str)> = None;

    loop {
        if let Some(q) = quote {
            let mut ignore = false;
            for i in ignored.iter() {
                if inp.as_str().starts_with(i) {
                    out.push_str(i);
                    inp = inp.as_str()[i.len()..].chars();
                    ignore = true;
                    break;
                }
            }
            if !ignore {
                if inp.as_str().starts_with(q.1) {
                    out.push_str(q.1);
                    inp = inp.as_str()[q.1.len()..].chars();
                    quote = None;
                } else {
                    if let Some(c) = inp.next() {
                        out.push(c);
                    } else {
                        break;
                    }
                }
            }
        } else {
            for q in quotes.iter() {
                if inp.as_str().starts_with(q.0) {
                    out.push_str(q.0);
                    inp = inp.as_str()[q.0.len()..].chars();
                    quote = Some(q);
                    break;
                }
            }
            if quote.is_none() {
                if let Some(c) = inp.next() {
                    if !c.is_whitespace() {
                        out.push(c);
                    }
                } else {
                    break;
                }
            }
        }
    }
    out
}