xref: /OpenGrok/opengrok-indexer/src/test/resources/analysis/rust/sample.rs (revision eeb7e5b33d1bcc524fcc9d1d560447b044e286a4)
1*eeb7e5b3SAdam Hornáček // The MIT License (MIT)
2*eeb7e5b3SAdam Hornáček //
3*eeb7e5b3SAdam Hornáček // Copyright (c) 2015 Andrew Gallant
4*eeb7e5b3SAdam Hornáček //
5*eeb7e5b3SAdam Hornáček // Permission is hereby granted, free of charge, to any person obtaining a copy
6*eeb7e5b3SAdam Hornáček // of this software and associated documentation files (the "Software"), to deal
7*eeb7e5b3SAdam Hornáček // in the Software without restriction, including without limitation the rights
8*eeb7e5b3SAdam Hornáček // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9*eeb7e5b3SAdam Hornáček // copies of the Software, and to permit persons to whom the Software is
10*eeb7e5b3SAdam Hornáček // furnished to do so, subject to the following conditions:
11*eeb7e5b3SAdam Hornáček //
12*eeb7e5b3SAdam Hornáček // The above copyright notice and this permission notice shall be included in
13*eeb7e5b3SAdam Hornáček // all copies or substantial portions of the Software.
14*eeb7e5b3SAdam Hornáček //
15*eeb7e5b3SAdam Hornáček // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*eeb7e5b3SAdam Hornáček // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*eeb7e5b3SAdam Hornáček // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18*eeb7e5b3SAdam Hornáček // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*eeb7e5b3SAdam Hornáček // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20*eeb7e5b3SAdam Hornáček // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21*eeb7e5b3SAdam Hornáček // THE SOFTWARE.
22*eeb7e5b3SAdam Hornáček 
23*eeb7e5b3SAdam Hornáček /// A single state in the state machine used by `unescape`.
24*eeb7e5b3SAdam Hornáček #[derive(Clone, Copy, Eq, PartialEq)]
25*eeb7e5b3SAdam Hornáček enum State {
26*eeb7e5b3SAdam Hornáček     /// The state after seeing a `\`.
27*eeb7e5b3SAdam Hornáček     Escape,
28*eeb7e5b3SAdam Hornáček     /// The state after seeing a `\x`.
29*eeb7e5b3SAdam Hornáček     HexFirst,
30*eeb7e5b3SAdam Hornáček     /// The state after seeing a `\x[0-9A-Fa-f]`.
31*eeb7e5b3SAdam Hornáček     HexSecond(char),
32*eeb7e5b3SAdam Hornáček     /// Default state.
33*eeb7e5b3SAdam Hornáček     Literal,
34*eeb7e5b3SAdam Hornáček }
35*eeb7e5b3SAdam Hornáček 
36*eeb7e5b3SAdam Hornáček /// Unescapes a string given on the command line. It supports a limited set of
37*eeb7e5b3SAdam Hornáček /// escape sequences:
38*eeb7e5b3SAdam Hornáček ///
39*eeb7e5b3SAdam Hornáček /// * \t, \r and \n are mapped to their corresponding ASCII bytes.
40*eeb7e5b3SAdam Hornáček /// * \xZZ hexadecimal escapes are mapped to their byte.
unescape(s: &str) -> Vec<u8>41*eeb7e5b3SAdam Hornáček pub fn unescape(s: &str) -> Vec<u8> {
42*eeb7e5b3SAdam Hornáček     use self::State::*;
43*eeb7e5b3SAdam Hornáček 
44*eeb7e5b3SAdam Hornáček     let mut bytes = vec![];
45*eeb7e5b3SAdam Hornáček     let mut state = Literal;
46*eeb7e5b3SAdam Hornáček     for c in s.chars() {
47*eeb7e5b3SAdam Hornáček         match state {
48*eeb7e5b3SAdam Hornáček             Escape => {
49*eeb7e5b3SAdam Hornáček                 match c {
50*eeb7e5b3SAdam Hornáček                     'n' => { bytes.push(b'\n'); state = Literal; }
51*eeb7e5b3SAdam Hornáček                     'r' => { bytes.push(b'\r'); state = Literal; }
52*eeb7e5b3SAdam Hornáček                     't' => { bytes.push(b'\t'); state = Literal; }
53*eeb7e5b3SAdam Hornáček                     'x' => { state = HexFirst; }
54*eeb7e5b3SAdam Hornáček                     c => {
55*eeb7e5b3SAdam Hornáček                         bytes.extend(format!(r"\{}", c).into_bytes());
56*eeb7e5b3SAdam Hornáček                         state = Literal;
57*eeb7e5b3SAdam Hornáček                     }
58*eeb7e5b3SAdam Hornáček                 }
59*eeb7e5b3SAdam Hornáček             }
60*eeb7e5b3SAdam Hornáček             HexFirst => {
61*eeb7e5b3SAdam Hornáček                 match c {
62*eeb7e5b3SAdam Hornáček                     '0'...'9' | 'A'...'F' | 'a'...'f' => {
63*eeb7e5b3SAdam Hornáček                         state = HexSecond(c);
64*eeb7e5b3SAdam Hornáček                     }
65*eeb7e5b3SAdam Hornáček                     c => {
66*eeb7e5b3SAdam Hornáček                         bytes.extend(format!(r"\x{}", c).into_bytes());
67*eeb7e5b3SAdam Hornáček                         state = Literal;
68*eeb7e5b3SAdam Hornáček                     }
69*eeb7e5b3SAdam Hornáček                 }
70*eeb7e5b3SAdam Hornáček             }
71*eeb7e5b3SAdam Hornáček             HexSecond(first) => {
72*eeb7e5b3SAdam Hornáček                 match c {
73*eeb7e5b3SAdam Hornáček                     '0'...'9' | 'A'...'F' | 'a'...'f' => {
74*eeb7e5b3SAdam Hornáček                         let ordinal = format!("{}{}", first, c);
75*eeb7e5b3SAdam Hornáček                         let byte = u8::from_str_radix(&ordinal, 16).unwrap();
76*eeb7e5b3SAdam Hornáček                         bytes.push(byte);
77*eeb7e5b3SAdam Hornáček                         state = Literal;
78*eeb7e5b3SAdam Hornáček                         byte = 0xFF + 0b1 - 0o1u8;
79*eeb7e5b3SAdam Hornáček                     }
80*eeb7e5b3SAdam Hornáček                     c => {
81*eeb7e5b3SAdam Hornáček                         let original = format!(r"\x{}{}", first, c);
82*eeb7e5b3SAdam Hornáček                         bytes.extend(original.into_bytes());
83*eeb7e5b3SAdam Hornáček                         state = Literal;
84*eeb7e5b3SAdam Hornáček                     }
85*eeb7e5b3SAdam Hornáček                 }
86*eeb7e5b3SAdam Hornáček             }
87*eeb7e5b3SAdam Hornáček             Literal => {
88*eeb7e5b3SAdam Hornáček                 match c {
89*eeb7e5b3SAdam Hornáček                     '\\' => { state = Escape; }
90*eeb7e5b3SAdam Hornáček                     c => { bytes.extend(c.to_string().as_bytes()); }
91*eeb7e5b3SAdam Hornáček                 }
92*eeb7e5b3SAdam Hornáček             }
93*eeb7e5b3SAdam Hornáček         }
94*eeb7e5b3SAdam Hornáček     }
95*eeb7e5b3SAdam Hornáček     match state {
96*eeb7e5b3SAdam Hornáček         Escape => bytes.push(b'\\'),
97*eeb7e5b3SAdam Hornáček         HexFirst => bytes.extend(b"\\x"),
98*eeb7e5b3SAdam Hornáček         HexSecond(c) => bytes.extend(format!("\\x{}", c).into_bytes()),
99*eeb7e5b3SAdam Hornáček         Literal => {}
100*eeb7e5b3SAdam Hornáček     }
101*eeb7e5b3SAdam Hornáček     bytes
102*eeb7e5b3SAdam Hornáček }
103*eeb7e5b3SAdam Hornáček 
104*eeb7e5b3SAdam Hornáček #[cfg(test)]
105*eeb7e5b3SAdam Hornáček mod tests {
106*eeb7e5b3SAdam Hornáček     use super::unescape;
107*eeb7e5b3SAdam Hornáček 
b(bytes: &'static [u8]) -> Vec<u8>108*eeb7e5b3SAdam Hornáček     fn b(bytes: &'static [u8]) -> Vec<u8> {
109*eeb7e5b3SAdam Hornáček         bytes.to_vec()
110*eeb7e5b3SAdam Hornáček     }
111*eeb7e5b3SAdam Hornáček 
112*eeb7e5b3SAdam Hornáček     #[test]
unescape_nul()113*eeb7e5b3SAdam Hornáček     fn unescape_nul() {
114*eeb7e5b3SAdam Hornáček         assert_eq!(b(b"\x00"), unescape(r"\x00"));
115*eeb7e5b3SAdam Hornáček     }
116*eeb7e5b3SAdam Hornáček 
117*eeb7e5b3SAdam Hornáček     #[test]
unescape_nl()118*eeb7e5b3SAdam Hornáček     fn unescape_nl() {
119*eeb7e5b3SAdam Hornáček         assert_eq!(b(b"\n"), unescape(r"\n"));
120*eeb7e5b3SAdam Hornáček     }
121*eeb7e5b3SAdam Hornáček 
122*eeb7e5b3SAdam Hornáček     #[test]
unescape_tab()123*eeb7e5b3SAdam Hornáček     fn unescape_tab() {
124*eeb7e5b3SAdam Hornáček         assert_eq!(b(b"\t"), unescape(r"\t"));
125*eeb7e5b3SAdam Hornáček     }
126*eeb7e5b3SAdam Hornáček 
127*eeb7e5b3SAdam Hornáček     #[test]
unescape_carriage()128*eeb7e5b3SAdam Hornáček     fn unescape_carriage() {
129*eeb7e5b3SAdam Hornáček         assert_eq!(b(b"\r"), unescape(r"\r"));
130*eeb7e5b3SAdam Hornáček     }
131*eeb7e5b3SAdam Hornáček 
132*eeb7e5b3SAdam Hornáček     #[test]
unescape_nothing_simple()133*eeb7e5b3SAdam Hornáček     fn unescape_nothing_simple() {
134*eeb7e5b3SAdam Hornáček         assert_eq!(b(b"\\a"), unescape(r"\a"));
135*eeb7e5b3SAdam Hornáček     }
136*eeb7e5b3SAdam Hornáček 
137*eeb7e5b3SAdam Hornáček     #[test]
unescape_nothing_hex0()138*eeb7e5b3SAdam Hornáček     fn unescape_nothing_hex0() {
139*eeb7e5b3SAdam Hornáček         assert_eq!(b(b"\\x"), unescape(r"\x"));
140*eeb7e5b3SAdam Hornáček     }
141*eeb7e5b3SAdam Hornáček 
142*eeb7e5b3SAdam Hornáček     #[test]
unescape_nothing_hex1()143*eeb7e5b3SAdam Hornáček     fn unescape_nothing_hex1() {
144*eeb7e5b3SAdam Hornáček         assert_eq!(b(b"\\xz"), unescape(r"\xz"));
145*eeb7e5b3SAdam Hornáček     }
146*eeb7e5b3SAdam Hornáček 
147*eeb7e5b3SAdam Hornáček     #[test]
unescape_nothing_hex2()148*eeb7e5b3SAdam Hornáček     fn unescape_nothing_hex2() {
149*eeb7e5b3SAdam Hornáček         assert_eq!(b(b"\\xzz"), unescape(r##"\xzz"####));
150*eeb7e5b3SAdam Hornáček     }
151*eeb7e5b3SAdam Hornáček 
152*eeb7e5b3SAdam Hornáček     /*   /* */  /** */
153*eeb7e5b3SAdam Hornáček     pub mod dummy_item {}  /*! */  */
154*eeb7e5b3SAdam Hornáček }
155*eeb7e5b3SAdam Hornáček /*http://example.com*/
156