actix / actix-extras
1
use std::str;
2

3
use actix_web::web::BytesMut;
4

5
enum State {
6
    YieldStr,
7
    YieldQuote,
8
}
9

10
struct Quoted<'a> {
11
    inner: ::std::iter::Peekable<str::Split<'a, char>>,
12
    state: State,
13
}
14

15
impl<'a> Quoted<'a> {
16 1
    pub fn new(s: &'a str) -> Quoted<'_> {
17
        Quoted {
18 1
            inner: s.split('"').peekable(),
19
            state: State::YieldStr,
20
        }
21
    }
22
}
23

24
impl<'a> Iterator for Quoted<'a> {
25
    type Item = &'a str;
26

27 1
    fn next(&mut self) -> Option<Self::Item> {
28 0
        match self.state {
29 1
            State::YieldStr => match self.inner.next() {
30 1
                Some(s) => {
31 1
                    self.state = State::YieldQuote;
32 1
                    Some(s)
33
                }
34 0
                None => None,
35
            },
36 1
            State::YieldQuote => match self.inner.peek() {
37 1
                Some(_) => {
38 1
                    self.state = State::YieldStr;
39
                    Some("\\\"")
40
                }
41 1
                None => None,
42
            },
43
        }
44
    }
45
}
46

47
/// Tries to quote the quotes in the passed `value`
48 1
pub fn put_quoted(buf: &mut BytesMut, value: &str) {
49 1
    for part in Quoted::new(value) {
50 1
        buf.extend_from_slice(part.as_bytes());
51
    }
52
}
53

54
#[cfg(test)]
55
mod tests {
56
    use std::str;
57

58
    use actix_web::web::BytesMut;
59

60
    use super::put_quoted;
61

62
    #[test]
63 1
    fn test_quote_str() {
64 1
        let input = "a \"quoted\" string";
65 1
        let mut output = BytesMut::new();
66 1
        put_quoted(&mut output, input);
67 1
        let result = str::from_utf8(&output).unwrap();
68

69 1
        assert_eq!(result, "a \\\"quoted\\\" string");
70
    }
71

72
    #[test]
73 1
    fn test_without_quotes() {
74 1
        let input = "non-quoted string";
75 1
        let mut output = BytesMut::new();
76 1
        put_quoted(&mut output, input);
77 1
        let result = str::from_utf8(&output).unwrap();
78

79 1
        assert_eq!(result, "non-quoted string");
80
    }
81

82
    #[test]
83 1
    fn test_starts_with_quote() {
84 1
        let input = "\"first-quoted string";
85 1
        let mut output = BytesMut::new();
86 1
        put_quoted(&mut output, input);
87 1
        let result = str::from_utf8(&output).unwrap();
88

89 1
        assert_eq!(result, "\\\"first-quoted string");
90
    }
91

92
    #[test]
93 1
    fn test_ends_with_quote() {
94 1
        let input = "last-quoted string\"";
95 1
        let mut output = BytesMut::new();
96 1
        put_quoted(&mut output, input);
97 1
        let result = str::from_utf8(&output).unwrap();
98

99 1
        assert_eq!(result, "last-quoted string\\\"");
100
    }
101

102
    #[test]
103 1
    fn test_double_quote() {
104 1
        let input = "quote\"\"string";
105 1
        let mut output = BytesMut::new();
106 1
        put_quoted(&mut output, input);
107 1
        let result = str::from_utf8(&output).unwrap();
108

109 1
        assert_eq!(result, "quote\\\"\\\"string");
110
    }
111
}

Read our documentation on viewing source code .

Loading