blob: 4425fcce4e49542881158670318ee87f10fba8ae [file] [log] [blame]
David Tolnay360efd22018-01-04 23:35:26 -08001extern crate proc_macro2;
David Tolnay61037c62018-01-05 16:21:03 -08002extern crate quote;
3extern crate syn;
David Tolnay360efd22018-01-04 23:35:26 -08004
David Tolnayc3f98562018-11-02 08:55:05 -07005mod features;
6
David Tolnayeb7d79b2018-03-31 22:52:17 +02007use proc_macro2::{TokenStream, TokenTree};
David Tolnay360efd22018-01-04 23:35:26 -08008use quote::ToTokens;
David Tolnay360efd22018-01-04 23:35:26 -08009use std::str::FromStr;
David Tolnayeb7d79b2018-03-31 22:52:17 +020010use syn::{FloatSuffix, IntSuffix, Lit};
David Tolnay360efd22018-01-04 23:35:26 -080011
12fn lit(s: &str) -> Lit {
David Tolnay61037c62018-01-05 16:21:03 -080013 match TokenStream::from_str(s)
14 .unwrap()
15 .into_iter()
16 .next()
17 .unwrap()
David Tolnay61037c62018-01-05 16:21:03 -080018 {
Alex Crichton9a4dca22018-03-28 06:32:19 -070019 TokenTree::Literal(lit) => Lit::new(lit),
David Tolnay360efd22018-01-04 23:35:26 -080020 _ => panic!(),
21 }
22}
23
24#[test]
25fn strings() {
26 fn test_string(s: &str, value: &str) {
27 match lit(s) {
28 Lit::Str(lit) => {
29 assert_eq!(lit.value(), value);
Alex Crichtoneaa6e432018-05-17 11:08:58 -070030 let again = lit.into_token_stream().to_string();
David Tolnay360efd22018-01-04 23:35:26 -080031 if again != s {
32 test_string(&again, value);
33 }
34 }
35 wrong => panic!("{:?}", wrong),
36 }
37 }
38
39 test_string("\"a\"", "a");
40 test_string("\"\\n\"", "\n");
41 test_string("\"\\r\"", "\r");
42 test_string("\"\\t\"", "\t");
43 test_string("\"🐕\"", "🐕"); // NOTE: This is an emoji
44 test_string("\"\\\"\"", "\"");
45 test_string("\"'\"", "'");
46 test_string("\"\"", "");
47 test_string("\"\\u{1F415}\"", "\u{1F415}");
David Tolnay61037c62018-01-05 16:21:03 -080048 test_string(
49 "\"contains\nnewlines\\\nescaped newlines\"",
50 "contains\nnewlinesescaped newlines",
51 );
David Tolnay360efd22018-01-04 23:35:26 -080052 test_string("r\"raw\nstring\\\nhere\"", "raw\nstring\\\nhere");
53}
54
55#[test]
56fn byte_strings() {
57 fn test_byte_string(s: &str, value: &[u8]) {
58 match lit(s) {
59 Lit::ByteStr(lit) => {
60 assert_eq!(lit.value(), value);
Alex Crichtoneaa6e432018-05-17 11:08:58 -070061 let again = lit.into_token_stream().to_string();
David Tolnay360efd22018-01-04 23:35:26 -080062 if again != s {
63 test_byte_string(&again, value);
64 }
65 }
66 wrong => panic!("{:?}", wrong),
67 }
68 }
69
70 test_byte_string("b\"a\"", b"a");
71 test_byte_string("b\"\\n\"", b"\n");
72 test_byte_string("b\"\\r\"", b"\r");
73 test_byte_string("b\"\\t\"", b"\t");
74 test_byte_string("b\"\\\"\"", b"\"");
75 test_byte_string("b\"'\"", b"'");
76 test_byte_string("b\"\"", b"");
David Tolnay61037c62018-01-05 16:21:03 -080077 test_byte_string(
78 "b\"contains\nnewlines\\\nescaped newlines\"",
79 b"contains\nnewlinesescaped newlines",
80 );
David Tolnay360efd22018-01-04 23:35:26 -080081 test_byte_string("br\"raw\nstring\\\nhere\"", b"raw\nstring\\\nhere");
82}
83
84#[test]
85fn bytes() {
86 fn test_byte(s: &str, value: u8) {
87 match lit(s) {
88 Lit::Byte(lit) => {
89 assert_eq!(lit.value(), value);
Alex Crichtoneaa6e432018-05-17 11:08:58 -070090 let again = lit.into_token_stream().to_string();
David Tolnay360efd22018-01-04 23:35:26 -080091 assert_eq!(again, s);
92 }
93 wrong => panic!("{:?}", wrong),
94 }
95 }
96
97 test_byte("b'a'", b'a');
98 test_byte("b'\\n'", b'\n');
99 test_byte("b'\\r'", b'\r');
100 test_byte("b'\\t'", b'\t');
101 test_byte("b'\\''", b'\'');
102 test_byte("b'\"'", b'"');
103}
104
105#[test]
106fn chars() {
107 fn test_char(s: &str, value: char) {
108 match lit(s) {
109 Lit::Char(lit) => {
110 assert_eq!(lit.value(), value);
Alex Crichtoneaa6e432018-05-17 11:08:58 -0700111 let again = lit.into_token_stream().to_string();
David Tolnay360efd22018-01-04 23:35:26 -0800112 if again != s {
113 test_char(&again, value);
114 }
115 }
116 wrong => panic!("{:?}", wrong),
117 }
118 }
119
120 test_char("'a'", 'a');
121 test_char("'\\n'", '\n');
122 test_char("'\\r'", '\r');
123 test_char("'\\t'", '\t');
124 test_char("'🐕'", '🐕'); // NOTE: This is an emoji
125 test_char("'\\''", '\'');
126 test_char("'\"'", '"');
127 test_char("'\\u{1F415}'", '\u{1F415}');
128}
129
130#[test]
131fn ints() {
132 fn test_int(s: &str, value: u64, suffix: IntSuffix) {
133 match lit(s) {
134 Lit::Int(lit) => {
135 assert_eq!(lit.value(), value);
136 assert_eq!(lit.suffix(), suffix);
Alex Crichtoneaa6e432018-05-17 11:08:58 -0700137 let again = lit.into_token_stream().to_string();
David Tolnay360efd22018-01-04 23:35:26 -0800138 if again != s {
139 test_int(&again, value, suffix);
140 }
141 }
142 wrong => panic!("{:?}", wrong),
143 }
144 }
145
146 use syn::IntSuffix::*;
147 test_int("5", 5, None);
148 test_int("5u32", 5, U32);
149 test_int("5_0", 50, None);
150 test_int("5_____0_____", 50, None);
151 test_int("0x7f", 127, None);
152 test_int("0x7F", 127, None);
153 test_int("0b1001", 9, None);
154 test_int("0o73", 59, None);
155 test_int("0x7Fu8", 127, U8);
156 test_int("0b1001i8", 9, I8);
157 test_int("0o73u32", 59, U32);
158 test_int("0x__7___f_", 127, None);
159 test_int("0x__7___F_", 127, None);
160 test_int("0b_1_0__01", 9, None);
161 test_int("0o_7__3", 59, None);
162 test_int("0x_7F__u8", 127, U8);
163 test_int("0b__10__0_1i8", 9, I8);
164 test_int("0o__7__________________3u32", 59, U32);
165}
166
167#[test]
168fn floats() {
David Tolnay76ebcdd2018-01-05 17:07:26 -0800169 #[cfg_attr(feature = "cargo-clippy", allow(float_cmp))]
David Tolnay360efd22018-01-04 23:35:26 -0800170 fn test_float(s: &str, value: f64, suffix: FloatSuffix) {
171 match lit(s) {
172 Lit::Float(lit) => {
173 assert_eq!(lit.value(), value);
174 assert_eq!(lit.suffix(), suffix);
Alex Crichtoneaa6e432018-05-17 11:08:58 -0700175 let again = lit.into_token_stream().to_string();
David Tolnay360efd22018-01-04 23:35:26 -0800176 if again != s {
177 test_float(&again, value, suffix);
178 }
179 }
180 wrong => panic!("{:?}", wrong),
181 }
182 }
183
184 use syn::FloatSuffix::*;
185 test_float("5.5", 5.5, None);
186 test_float("5.5E12", 5.5e12, None);
187 test_float("5.5e12", 5.5e12, None);
188 test_float("1.0__3e-12", 1.03e-12, None);
189 test_float("1.03e+12", 1.03e12, None);
190}