David Tolnay | 5553501 | 2018-01-05 16:39:23 -0800 | [diff] [blame] | 1 | // Copyright 2018 Syn Developers |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or |
| 4 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license |
| 5 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your |
| 6 | // option. This file may not be copied, modified, or distributed |
| 7 | // except according to those terms. |
| 8 | |
David Tolnay | 360efd2 | 2018-01-04 23:35:26 -0800 | [diff] [blame] | 9 | extern crate proc_macro2; |
David Tolnay | 61037c6 | 2018-01-05 16:21:03 -0800 | [diff] [blame] | 10 | extern crate quote; |
| 11 | extern crate syn; |
David Tolnay | 360efd2 | 2018-01-04 23:35:26 -0800 | [diff] [blame] | 12 | |
David Tolnay | c3f9856 | 2018-11-02 08:55:05 -0700 | [diff] [blame^] | 13 | mod features; |
| 14 | |
David Tolnay | eb7d79b | 2018-03-31 22:52:17 +0200 | [diff] [blame] | 15 | use proc_macro2::{TokenStream, TokenTree}; |
David Tolnay | 360efd2 | 2018-01-04 23:35:26 -0800 | [diff] [blame] | 16 | use quote::ToTokens; |
David Tolnay | 360efd2 | 2018-01-04 23:35:26 -0800 | [diff] [blame] | 17 | use std::str::FromStr; |
David Tolnay | eb7d79b | 2018-03-31 22:52:17 +0200 | [diff] [blame] | 18 | use syn::{FloatSuffix, IntSuffix, Lit}; |
David Tolnay | 360efd2 | 2018-01-04 23:35:26 -0800 | [diff] [blame] | 19 | |
| 20 | fn lit(s: &str) -> Lit { |
David Tolnay | 61037c6 | 2018-01-05 16:21:03 -0800 | [diff] [blame] | 21 | match TokenStream::from_str(s) |
| 22 | .unwrap() |
| 23 | .into_iter() |
| 24 | .next() |
| 25 | .unwrap() |
David Tolnay | 61037c6 | 2018-01-05 16:21:03 -0800 | [diff] [blame] | 26 | { |
Alex Crichton | 9a4dca2 | 2018-03-28 06:32:19 -0700 | [diff] [blame] | 27 | TokenTree::Literal(lit) => Lit::new(lit), |
David Tolnay | 360efd2 | 2018-01-04 23:35:26 -0800 | [diff] [blame] | 28 | _ => panic!(), |
| 29 | } |
| 30 | } |
| 31 | |
| 32 | #[test] |
| 33 | fn strings() { |
| 34 | fn test_string(s: &str, value: &str) { |
| 35 | match lit(s) { |
| 36 | Lit::Str(lit) => { |
| 37 | assert_eq!(lit.value(), value); |
Alex Crichton | eaa6e43 | 2018-05-17 11:08:58 -0700 | [diff] [blame] | 38 | let again = lit.into_token_stream().to_string(); |
David Tolnay | 360efd2 | 2018-01-04 23:35:26 -0800 | [diff] [blame] | 39 | if again != s { |
| 40 | test_string(&again, value); |
| 41 | } |
| 42 | } |
| 43 | wrong => panic!("{:?}", wrong), |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | test_string("\"a\"", "a"); |
| 48 | test_string("\"\\n\"", "\n"); |
| 49 | test_string("\"\\r\"", "\r"); |
| 50 | test_string("\"\\t\"", "\t"); |
| 51 | test_string("\"🐕\"", "🐕"); // NOTE: This is an emoji |
| 52 | test_string("\"\\\"\"", "\""); |
| 53 | test_string("\"'\"", "'"); |
| 54 | test_string("\"\"", ""); |
| 55 | test_string("\"\\u{1F415}\"", "\u{1F415}"); |
David Tolnay | 61037c6 | 2018-01-05 16:21:03 -0800 | [diff] [blame] | 56 | test_string( |
| 57 | "\"contains\nnewlines\\\nescaped newlines\"", |
| 58 | "contains\nnewlinesescaped newlines", |
| 59 | ); |
David Tolnay | 360efd2 | 2018-01-04 23:35:26 -0800 | [diff] [blame] | 60 | test_string("r\"raw\nstring\\\nhere\"", "raw\nstring\\\nhere"); |
| 61 | } |
| 62 | |
| 63 | #[test] |
| 64 | fn byte_strings() { |
| 65 | fn test_byte_string(s: &str, value: &[u8]) { |
| 66 | match lit(s) { |
| 67 | Lit::ByteStr(lit) => { |
| 68 | assert_eq!(lit.value(), value); |
Alex Crichton | eaa6e43 | 2018-05-17 11:08:58 -0700 | [diff] [blame] | 69 | let again = lit.into_token_stream().to_string(); |
David Tolnay | 360efd2 | 2018-01-04 23:35:26 -0800 | [diff] [blame] | 70 | if again != s { |
| 71 | test_byte_string(&again, value); |
| 72 | } |
| 73 | } |
| 74 | wrong => panic!("{:?}", wrong), |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | test_byte_string("b\"a\"", b"a"); |
| 79 | test_byte_string("b\"\\n\"", b"\n"); |
| 80 | test_byte_string("b\"\\r\"", b"\r"); |
| 81 | test_byte_string("b\"\\t\"", b"\t"); |
| 82 | test_byte_string("b\"\\\"\"", b"\""); |
| 83 | test_byte_string("b\"'\"", b"'"); |
| 84 | test_byte_string("b\"\"", b""); |
David Tolnay | 61037c6 | 2018-01-05 16:21:03 -0800 | [diff] [blame] | 85 | test_byte_string( |
| 86 | "b\"contains\nnewlines\\\nescaped newlines\"", |
| 87 | b"contains\nnewlinesescaped newlines", |
| 88 | ); |
David Tolnay | 360efd2 | 2018-01-04 23:35:26 -0800 | [diff] [blame] | 89 | test_byte_string("br\"raw\nstring\\\nhere\"", b"raw\nstring\\\nhere"); |
| 90 | } |
| 91 | |
| 92 | #[test] |
| 93 | fn bytes() { |
| 94 | fn test_byte(s: &str, value: u8) { |
| 95 | match lit(s) { |
| 96 | Lit::Byte(lit) => { |
| 97 | assert_eq!(lit.value(), value); |
Alex Crichton | eaa6e43 | 2018-05-17 11:08:58 -0700 | [diff] [blame] | 98 | let again = lit.into_token_stream().to_string(); |
David Tolnay | 360efd2 | 2018-01-04 23:35:26 -0800 | [diff] [blame] | 99 | assert_eq!(again, s); |
| 100 | } |
| 101 | wrong => panic!("{:?}", wrong), |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | test_byte("b'a'", b'a'); |
| 106 | test_byte("b'\\n'", b'\n'); |
| 107 | test_byte("b'\\r'", b'\r'); |
| 108 | test_byte("b'\\t'", b'\t'); |
| 109 | test_byte("b'\\''", b'\''); |
| 110 | test_byte("b'\"'", b'"'); |
| 111 | } |
| 112 | |
| 113 | #[test] |
| 114 | fn chars() { |
| 115 | fn test_char(s: &str, value: char) { |
| 116 | match lit(s) { |
| 117 | Lit::Char(lit) => { |
| 118 | assert_eq!(lit.value(), value); |
Alex Crichton | eaa6e43 | 2018-05-17 11:08:58 -0700 | [diff] [blame] | 119 | let again = lit.into_token_stream().to_string(); |
David Tolnay | 360efd2 | 2018-01-04 23:35:26 -0800 | [diff] [blame] | 120 | if again != s { |
| 121 | test_char(&again, value); |
| 122 | } |
| 123 | } |
| 124 | wrong => panic!("{:?}", wrong), |
| 125 | } |
| 126 | } |
| 127 | |
| 128 | test_char("'a'", 'a'); |
| 129 | test_char("'\\n'", '\n'); |
| 130 | test_char("'\\r'", '\r'); |
| 131 | test_char("'\\t'", '\t'); |
| 132 | test_char("'🐕'", '🐕'); // NOTE: This is an emoji |
| 133 | test_char("'\\''", '\''); |
| 134 | test_char("'\"'", '"'); |
| 135 | test_char("'\\u{1F415}'", '\u{1F415}'); |
| 136 | } |
| 137 | |
| 138 | #[test] |
| 139 | fn ints() { |
| 140 | fn test_int(s: &str, value: u64, suffix: IntSuffix) { |
| 141 | match lit(s) { |
| 142 | Lit::Int(lit) => { |
| 143 | assert_eq!(lit.value(), value); |
| 144 | assert_eq!(lit.suffix(), suffix); |
Alex Crichton | eaa6e43 | 2018-05-17 11:08:58 -0700 | [diff] [blame] | 145 | let again = lit.into_token_stream().to_string(); |
David Tolnay | 360efd2 | 2018-01-04 23:35:26 -0800 | [diff] [blame] | 146 | if again != s { |
| 147 | test_int(&again, value, suffix); |
| 148 | } |
| 149 | } |
| 150 | wrong => panic!("{:?}", wrong), |
| 151 | } |
| 152 | } |
| 153 | |
| 154 | use syn::IntSuffix::*; |
| 155 | test_int("5", 5, None); |
| 156 | test_int("5u32", 5, U32); |
| 157 | test_int("5_0", 50, None); |
| 158 | test_int("5_____0_____", 50, None); |
| 159 | test_int("0x7f", 127, None); |
| 160 | test_int("0x7F", 127, None); |
| 161 | test_int("0b1001", 9, None); |
| 162 | test_int("0o73", 59, None); |
| 163 | test_int("0x7Fu8", 127, U8); |
| 164 | test_int("0b1001i8", 9, I8); |
| 165 | test_int("0o73u32", 59, U32); |
| 166 | test_int("0x__7___f_", 127, None); |
| 167 | test_int("0x__7___F_", 127, None); |
| 168 | test_int("0b_1_0__01", 9, None); |
| 169 | test_int("0o_7__3", 59, None); |
| 170 | test_int("0x_7F__u8", 127, U8); |
| 171 | test_int("0b__10__0_1i8", 9, I8); |
| 172 | test_int("0o__7__________________3u32", 59, U32); |
| 173 | } |
| 174 | |
| 175 | #[test] |
| 176 | fn floats() { |
David Tolnay | 76ebcdd | 2018-01-05 17:07:26 -0800 | [diff] [blame] | 177 | #[cfg_attr(feature = "cargo-clippy", allow(float_cmp))] |
David Tolnay | 360efd2 | 2018-01-04 23:35:26 -0800 | [diff] [blame] | 178 | fn test_float(s: &str, value: f64, suffix: FloatSuffix) { |
| 179 | match lit(s) { |
| 180 | Lit::Float(lit) => { |
| 181 | assert_eq!(lit.value(), value); |
| 182 | assert_eq!(lit.suffix(), suffix); |
Alex Crichton | eaa6e43 | 2018-05-17 11:08:58 -0700 | [diff] [blame] | 183 | let again = lit.into_token_stream().to_string(); |
David Tolnay | 360efd2 | 2018-01-04 23:35:26 -0800 | [diff] [blame] | 184 | if again != s { |
| 185 | test_float(&again, value, suffix); |
| 186 | } |
| 187 | } |
| 188 | wrong => panic!("{:?}", wrong), |
| 189 | } |
| 190 | } |
| 191 | |
| 192 | use syn::FloatSuffix::*; |
| 193 | test_float("5.5", 5.5, None); |
| 194 | test_float("5.5E12", 5.5e12, None); |
| 195 | test_float("5.5e12", 5.5e12, None); |
| 196 | test_float("1.0__3e-12", 1.03e-12, None); |
| 197 | test_float("1.03e+12", 1.03e12, None); |
| 198 | } |