1 use std::fmt::{Debug, Display};
2 use crate::{
3 FromIntegerLiteral, Literal, IntegerLit, IntegerType as Ty, IntegerBase, IntegerBase::*,
4 test_util::{assert_parse_ok_eq, assert_roundtrip},
5 };
6
7
8 // ===== Utility functions =======================================================================
9
10 #[track_caller]
check<T: FromIntegerLiteral + PartialEq + Debug + Display>( input: &str, value: T, base: IntegerBase, main_part: &str, type_suffix: Option<Ty>, )11 fn check<T: FromIntegerLiteral + PartialEq + Debug + Display>(
12 input: &str,
13 value: T,
14 base: IntegerBase,
15 main_part: &str,
16 type_suffix: Option<Ty>,
17 ) {
18 let expected_integer = IntegerLit {
19 raw: input,
20 start_main_part: base.prefix().len(),
21 end_main_part: base.prefix().len() + main_part.len(),
22 base,
23 type_suffix
24 };
25 assert_parse_ok_eq(
26 input, IntegerLit::parse(input), expected_integer.clone(), "IntegerLit::parse");
27 assert_parse_ok_eq(
28 input, Literal::parse(input), Literal::Integer(expected_integer), "Literal::parse");
29 assert_roundtrip(expected_integer.to_owned(), input);
30
31 let actual_value = IntegerLit::parse(input)
32 .unwrap()
33 .value::<T>()
34 .unwrap_or_else(|| panic!("unexpected overflow in `IntegerLit::value` for `{}`", input));
35 if actual_value != value {
36 panic!(
37 "Parsing int literal `{}` should give value `{}`, but actually resulted in `{}`",
38 input,
39 value,
40 actual_value,
41 );
42 }
43 }
44
45
46 // ===== Actual tests ===========================================================================
47
48 #[test]
parse_decimal()49 fn parse_decimal() {
50 check("0", 0u128, Decimal, "0", None);
51 check("1", 1u8, Decimal, "1", None);
52 check("8", 8u16, Decimal, "8", None);
53 check("9", 9u32, Decimal, "9", None);
54 check("10", 10u64, Decimal, "10", None);
55 check("11", 11i8, Decimal, "11", None);
56 check("123456789", 123456789i128, Decimal, "123456789", None);
57
58 check("05", 5i16, Decimal, "05", None);
59 check("00005", 5i32, Decimal, "00005", None);
60 check("0123456789", 123456789i64, Decimal, "0123456789", None);
61
62 check("123_456_789", 123_456_789, Decimal, "123_456_789", None);
63 check("0___4", 4, Decimal, "0___4", None);
64 check("0___4_3", 43, Decimal, "0___4_3", None);
65 check("0___4_3", 43, Decimal, "0___4_3", None);
66 check("123___________", 123, Decimal, "123___________", None);
67
68 check(
69 "340282366920938463463374607431768211455",
70 340282366920938463463374607431768211455u128,
71 Decimal,
72 "340282366920938463463374607431768211455",
73 None,
74 );
75 check(
76 "340_282_366_920_938_463_463_374_607_431_768_211_455",
77 340282366920938463463374607431768211455u128,
78 Decimal,
79 "340_282_366_920_938_463_463_374_607_431_768_211_455",
80 None,
81 );
82 check(
83 "3_40_282_3669_20938_463463_3746074_31768211_455___",
84 340282366920938463463374607431768211455u128,
85 Decimal,
86 "3_40_282_3669_20938_463463_3746074_31768211_455___",
87 None,
88 );
89 }
90
91 #[test]
parse_binary()92 fn parse_binary() {
93 check("0b0", 0b0, Binary, "0", None);
94 check("0b000", 0b000, Binary, "000", None);
95 check("0b1", 0b1, Binary, "1", None);
96 check("0b01", 0b01, Binary, "01", None);
97 check("0b101010", 0b101010, Binary, "101010", None);
98 check("0b10_10_10", 0b10_10_10, Binary, "10_10_10", None);
99 check("0b01101110____", 0b01101110____, Binary, "01101110____", None);
100
101 check("0b10010u8", 0b10010u8, Binary, "10010", Some(Ty::U8));
102 check("0b10010i8", 0b10010u8, Binary, "10010", Some(Ty::I8));
103 check("0b10010u64", 0b10010u64, Binary, "10010", Some(Ty::U64));
104 check("0b10010i64", 0b10010u64, Binary, "10010", Some(Ty::I64));
105 check(
106 "0b1011001_00110000_00101000_10100101u32",
107 0b1011001_00110000_00101000_10100101u32,
108 Binary,
109 "1011001_00110000_00101000_10100101",
110 Some(Ty::U32),
111 );
112 }
113
114 #[test]
parse_octal()115 fn parse_octal() {
116 check("0o0", 0o0, Octal, "0", None);
117 check("0o1", 0o1, Octal, "1", None);
118 check("0o6", 0o6, Octal, "6", None);
119 check("0o7", 0o7, Octal, "7", None);
120 check("0o17", 0o17, Octal, "17", None);
121 check("0o123", 0o123, Octal, "123", None);
122 check("0o7654321", 0o7654321, Octal, "7654321", None);
123 check("0o7_53_1", 0o7_53_1, Octal, "7_53_1", None);
124 check("0o66_", 0o66_, Octal, "66_", None);
125
126 check("0o755u16", 0o755u16, Octal, "755", Some(Ty::U16));
127 check("0o755i128", 0o755i128, Octal, "755", Some(Ty::I128));
128 }
129
130 #[test]
parse_hexadecimal()131 fn parse_hexadecimal() {
132 check("0x0", 0x0, Hexadecimal, "0", None);
133 check("0x1", 0x1, Hexadecimal, "1", None);
134 check("0x9", 0x9, Hexadecimal, "9", None);
135
136 check("0xa", 0xa, Hexadecimal, "a", None);
137 check("0xf", 0xf, Hexadecimal, "f", None);
138 check("0x17", 0x17, Hexadecimal, "17", None);
139 check("0x1b", 0x1b, Hexadecimal, "1b", None);
140 check("0x123", 0x123, Hexadecimal, "123", None);
141 check("0xace", 0xace, Hexadecimal, "ace", None);
142 check("0xfdb971", 0xfdb971, Hexadecimal, "fdb971", None);
143 check("0xa_54_f", 0xa_54_f, Hexadecimal, "a_54_f", None);
144 check("0x6d_", 0x6d_, Hexadecimal, "6d_", None);
145
146 check("0xA", 0xA, Hexadecimal, "A", None);
147 check("0xF", 0xF, Hexadecimal, "F", None);
148 check("0x17", 0x17, Hexadecimal, "17", None);
149 check("0x1B", 0x1B, Hexadecimal, "1B", None);
150 check("0x123", 0x123, Hexadecimal, "123", None);
151 check("0xACE", 0xACE, Hexadecimal, "ACE", None);
152 check("0xFDB971", 0xFDB971, Hexadecimal, "FDB971", None);
153 check("0xA_54_F", 0xA_54_F, Hexadecimal, "A_54_F", None);
154 check("0x6D_", 0x6D_, Hexadecimal, "6D_", None);
155
156 check("0xFdB97a1", 0xFdB97a1, Hexadecimal, "FdB97a1", None);
157 check("0xfdB97A1", 0xfdB97A1, Hexadecimal, "fdB97A1", None);
158
159 check("0x40u16", 0x40u16, Hexadecimal, "40", Some(Ty::U16));
160 check("0xffi128", 0xffi128, Hexadecimal, "ff", Some(Ty::I128));
161 }
162
163 #[test]
starting_underscore()164 fn starting_underscore() {
165 check("0b_1", 1, Binary, "_1", None);
166 check("0b_010i16", 0b_010, Binary, "_010", Some(Ty::I16));
167
168 check("0o_5", 5, Octal, "_5", None);
169 check("0o_750u128", 0o_750u128, Octal, "_750", Some(Ty::U128));
170
171 check("0x_c", 0xc, Hexadecimal, "_c", None);
172 check("0x_cf3i8", 0x_cf3, Hexadecimal, "_cf3", Some(Ty::I8));
173 }
174
175 #[test]
parse_overflowing_just_fine()176 fn parse_overflowing_just_fine() {
177 check("256u8", 256u16, Decimal, "256", Some(Ty::U8));
178 check("123_456_789u8", 123_456_789u32, Decimal, "123_456_789", Some(Ty::U8));
179 check("123_456_789u16", 123_456_789u32, Decimal, "123_456_789", Some(Ty::U16));
180
181 check("123_123_456_789u8", 123_123_456_789u64, Decimal, "123_123_456_789", Some(Ty::U8));
182 check("123_123_456_789u16", 123_123_456_789u64, Decimal, "123_123_456_789", Some(Ty::U16));
183 check("123_123_456_789u32", 123_123_456_789u64, Decimal, "123_123_456_789", Some(Ty::U32));
184 }
185
186 #[test]
suffixes()187 fn suffixes() {
188 [
189 ("123i8", Ty::I8),
190 ("123i16", Ty::I16),
191 ("123i32", Ty::I32),
192 ("123i64", Ty::I64),
193 ("123i128", Ty::I128),
194 ("123u8", Ty::U8),
195 ("123u16", Ty::U16),
196 ("123u32", Ty::U32),
197 ("123u64", Ty::U64),
198 ("123u128", Ty::U128),
199 ].iter().for_each(|&(s, ty)| {
200 assert_eq!(IntegerLit::parse(s).unwrap().type_suffix(), Some(ty));
201 });
202 }
203
204 #[test]
overflow_u128()205 fn overflow_u128() {
206 let inputs = [
207 "340282366920938463463374607431768211456",
208 "0x100000000000000000000000000000000",
209 "0o4000000000000000000000000000000000000000000",
210 "0b1000000000000000000000000000000000000000000000000000000000000000000\
211 00000000000000000000000000000000000000000000000000000000000000",
212 "340282366920938463463374607431768211456u128",
213 "340282366920938463463374607431768211457",
214 "3_40_282_3669_20938_463463_3746074_31768211_456___",
215 "3_40_282_3669_20938_463463_3746074_31768211_455___1",
216 "3_40_282_3669_20938_463463_3746074_31768211_455___0u128",
217 "3402823669209384634633746074317682114570",
218 ];
219
220 for &input in &inputs {
221 let lit = IntegerLit::parse(input).expect("failed to parse");
222 assert!(lit.value::<u128>().is_none());
223 }
224 }
225
226 #[test]
overflow_u8()227 fn overflow_u8() {
228 let inputs = [
229 "256", "0x100", "0o400", "0b100000000",
230 "257", "0x101", "0o401", "0b100000001",
231 "300",
232 "1548",
233 "2548985",
234 "256u128",
235 "256u8",
236 "2_5_6",
237 "256_____1",
238 "256__",
239 ];
240
241 for &input in &inputs {
242 let lit = IntegerLit::parse(input).expect("failed to parse");
243 assert!(lit.value::<u8>().is_none());
244 }
245 }
246
247 #[test]
parse_err()248 fn parse_err() {
249 assert_err!(IntegerLit, "", Empty, None);
250 assert_err_single!(IntegerLit::parse("a"), DoesNotStartWithDigit, 0);
251 assert_err_single!(IntegerLit::parse(";"), DoesNotStartWithDigit, 0);
252 assert_err_single!(IntegerLit::parse("0;"), InvalidIntegerTypeSuffix, 1..2);
253 assert_err_single!(IntegerLit::parse("0a"), InvalidDigit, 1);
254 assert_err!(IntegerLit, "0b", NoDigits, 2..2);
255 assert_err_single!(IntegerLit::parse("0z"), InvalidIntegerTypeSuffix, 1..2);
256 assert_err_single!(IntegerLit::parse(" 0"), DoesNotStartWithDigit, 0);
257 assert_err_single!(IntegerLit::parse("0 "), InvalidIntegerTypeSuffix, 1);
258 assert_err_single!(IntegerLit::parse("0a3"), InvalidDigit, 1);
259 assert_err!(IntegerLit, "0b3", InvalidDigit, 2);
260 assert_err_single!(IntegerLit::parse("0z3"), InvalidIntegerTypeSuffix, 1..3);
261 assert_err_single!(IntegerLit::parse("_"), DoesNotStartWithDigit, 0);
262 assert_err_single!(IntegerLit::parse("_3"), DoesNotStartWithDigit, 0);
263 }
264
265 #[test]
invalid_digits()266 fn invalid_digits() {
267 assert_err!(IntegerLit, "0b10201", InvalidDigit, 4);
268 assert_err!(IntegerLit, "0b9", InvalidDigit, 2);
269 assert_err!(IntegerLit, "0b07", InvalidDigit, 3);
270 assert_err!(IntegerLit, "0b0a", InvalidDigit, 3);
271 assert_err!(IntegerLit, "0b0A", InvalidDigit, 3);
272 assert_err!(IntegerLit, "0b01f", InvalidDigit, 4);
273 assert_err!(IntegerLit, "0b01F", InvalidDigit, 4);
274
275 assert_err!(IntegerLit, "0o12380", InvalidDigit, 5);
276 assert_err!(IntegerLit, "0o192", InvalidDigit, 3);
277 assert_err!(IntegerLit, "0o7a_", InvalidDigit, 3);
278 assert_err!(IntegerLit, "0o7A_", InvalidDigit, 3);
279 assert_err!(IntegerLit, "0o72f_0", InvalidDigit, 4);
280 assert_err!(IntegerLit, "0o72F_0", InvalidDigit, 4);
281
282 assert_err_single!(IntegerLit::parse("12a3"), InvalidDigit, 2);
283 assert_err_single!(IntegerLit::parse("12f3"), InvalidDigit, 2);
284 assert_err_single!(IntegerLit::parse("12f_"), InvalidDigit, 2);
285 assert_err_single!(IntegerLit::parse("12F_"), InvalidDigit, 2);
286 assert_err_single!(IntegerLit::parse("a_123"), DoesNotStartWithDigit, 0);
287 assert_err_single!(IntegerLit::parse("B_123"), DoesNotStartWithDigit, 0);
288
289 assert_err!(IntegerLit, "0x8cg", InvalidIntegerTypeSuffix, 4..5);
290 assert_err!(IntegerLit, "0x8cG", InvalidIntegerTypeSuffix, 4..5);
291 assert_err!(IntegerLit, "0x8c1h_", InvalidIntegerTypeSuffix, 5..7);
292 assert_err!(IntegerLit, "0x8c1H_", InvalidIntegerTypeSuffix, 5..7);
293 assert_err!(IntegerLit, "0x8czu16", InvalidIntegerTypeSuffix, 4..8);
294 }
295
296 #[test]
no_valid_digits()297 fn no_valid_digits() {
298 assert_err!(IntegerLit, "0x_", NoDigits, 2..3);
299 assert_err!(IntegerLit, "0x__", NoDigits, 2..4);
300 assert_err!(IntegerLit, "0x________", NoDigits, 2..10);
301 assert_err!(IntegerLit, "0x_i8", NoDigits, 2..3);
302 assert_err!(IntegerLit, "0x_u8", NoDigits, 2..3);
303 assert_err!(IntegerLit, "0x_isize", NoDigits, 2..3);
304 assert_err!(IntegerLit, "0x_usize", NoDigits, 2..3);
305
306 assert_err!(IntegerLit, "0o_", NoDigits, 2..3);
307 assert_err!(IntegerLit, "0o__", NoDigits, 2..4);
308 assert_err!(IntegerLit, "0o________", NoDigits, 2..10);
309 assert_err!(IntegerLit, "0o_i32", NoDigits, 2..3);
310 assert_err!(IntegerLit, "0o_u32", NoDigits, 2..3);
311
312 assert_err!(IntegerLit, "0b_", NoDigits, 2..3);
313 assert_err!(IntegerLit, "0b__", NoDigits, 2..4);
314 assert_err!(IntegerLit, "0b________", NoDigits, 2..10);
315 assert_err!(IntegerLit, "0b_i128", NoDigits, 2..3);
316 assert_err!(IntegerLit, "0b_u128", NoDigits, 2..3);
317 }
318
319 #[test]
invalid_suffix()320 fn invalid_suffix() {
321 assert_err!(IntegerLit, "5u7", InvalidIntegerTypeSuffix, 1..3);
322 assert_err!(IntegerLit, "5u9", InvalidIntegerTypeSuffix, 1..3);
323 assert_err!(IntegerLit, "5u0", InvalidIntegerTypeSuffix, 1..3);
324 assert_err!(IntegerLit, "33u12", InvalidIntegerTypeSuffix, 2..5);
325 assert_err!(IntegerLit, "84u17", InvalidIntegerTypeSuffix, 2..5);
326 assert_err!(IntegerLit, "99u80", InvalidIntegerTypeSuffix, 2..5);
327 assert_err!(IntegerLit, "1234uu16", InvalidIntegerTypeSuffix, 4..8);
328
329 assert_err!(IntegerLit, "5i7", InvalidIntegerTypeSuffix, 1..3);
330 assert_err!(IntegerLit, "5i9", InvalidIntegerTypeSuffix, 1..3);
331 assert_err!(IntegerLit, "5i0", InvalidIntegerTypeSuffix, 1..3);
332 assert_err!(IntegerLit, "33i12", InvalidIntegerTypeSuffix, 2..5);
333 assert_err!(IntegerLit, "84i17", InvalidIntegerTypeSuffix, 2..5);
334 assert_err!(IntegerLit, "99i80", InvalidIntegerTypeSuffix, 2..5);
335 assert_err!(IntegerLit, "1234ii16", InvalidIntegerTypeSuffix, 4..8);
336
337 assert_err!(IntegerLit, "0ui32", InvalidIntegerTypeSuffix, 1..5);
338 assert_err!(IntegerLit, "1iu32", InvalidIntegerTypeSuffix, 1..5);
339 assert_err_single!(IntegerLit::parse("54321a64"), InvalidDigit, 5);
340 assert_err!(IntegerLit, "54321b64", InvalidDigit, 5);
341 assert_err!(IntegerLit, "54321x64", InvalidIntegerTypeSuffix, 5..8);
342 assert_err!(IntegerLit, "54321o64", InvalidIntegerTypeSuffix, 5..8);
343 }
344