1use nom::{
39 hex_digit,
40 oct_digit
41};
42use std::num::ParseIntError;
43use std::result::Result as StdResult;
44use std::str::FromStr;
45use std::str;
46use super::super::ast::Literal;
47use super::super::internal::{
48 Error,
49 ErrorKind,
50 Result
51};
52use super::tokens;
53
54named!(
55 pub literal<Literal>,
56 alt!(
57 null
58 | boolean
59 | exponential
60 | integer
61 | string
62 )
63);
64
65named!(
66 pub null<Literal>,
67 map_res!(
68 itag!("null"),
69 |_| -> StdResult<Literal, ()> {
70 Ok(Literal::Null)
71 }
72 )
73);
74
75named!(
76 pub boolean<Literal>,
77 map_res!(
78 alt!(itag!(&b"true"[..]) | itag!(&b"false"[..])),
79 |bytes: &[u8]| -> StdResult<Literal, ()> {
80 Ok(Literal::Boolean(bytes[0] == 't' as u8))
81 }
82 )
83);
84
85named!(
86 pub integer<Literal>,
87 alt_complete!(
88 binary
89 | decimal
90 | hexadecimal
91 | octal
92 )
93);
94
95named!(
96 pub binary<Literal>,
97 map_res!(
98 preceded!(
99 tag!("0"),
100 preceded!(
101 is_a!("bB"),
102 is_a!("01")
103 )
104 ),
105 |bytes: &[u8]| {
106 i64
107 ::from_str_radix(
108 unsafe { str::from_utf8_unchecked(bytes) },
109 2
110 )
111 .and_then(
112 |binary| {
113 Ok(Literal::Integer(binary))
114 }
115 )
116 }
117 )
118);
119
120named!(
121 pub octal<Literal>,
122 map_res!(
123 preceded!(tag!("0"), opt!(oct_digit)),
124 |value: Option<&[u8]>| {
125 match value {
126 Some(bytes) =>
127 i64
128 ::from_str_radix(
129 unsafe { str::from_utf8_unchecked(bytes) },
130 8
131 )
132 .and_then(
133 |octal| {
134 Ok(Literal::Integer(octal))
135 }
136 ),
137
138 None =>
139 Ok(Literal::Integer(0i64))
140 }
141 }
142 )
143);
144
145named!(
146 pub decimal<Literal>,
147 map_res!(
148 re_bytes_find_static!(r"^[1-9][0-9]*"),
149 |bytes: &[u8]| {
150 let string = unsafe { str::from_utf8_unchecked(bytes) };
151
152 i64
153 ::from_str(string)
154 .and_then(
155 |decimal| {
156 Ok(Literal::Integer(decimal))
157 }
158 )
159 .or_else(
160 |_: ParseIntError| {
161 f64
162 ::from_str(string)
163 .and_then(
164 |decimal| {
165 Ok(Literal::Real(decimal))
166 }
167 )
168 }
169 )
170 }
171 )
172);
173
174named!(
175 pub hexadecimal<Literal>,
176 map_res!(
177 preceded!(
178 tag!("0"),
179 preceded!(
180 is_a!("xX"),
181 hex_digit
182 )
183 ),
184 |bytes: &[u8]| {
185 i64
186 ::from_str_radix(
187 unsafe { str::from_utf8_unchecked(bytes) },
188 16
189 )
190 .and_then(
191 |hexadecimal| {
192 Ok(Literal::Integer(hexadecimal))
193 }
194 )
195 }
196 )
197);
198
199named!(
200 pub exponential<Literal>,
201 map_res!(
202 re_bytes_find_static!(r"^(([0-9]*\.[0-9]+|[0-9]+\.)([eE][+-]?[0-9]+)?|[0-9]+[eE][+-]?[0-9]+)"),
203 |bytes: &[u8]| {
204 f64
205 ::from_str(unsafe { str::from_utf8_unchecked(bytes) })
206 .and_then(
207 |exponential| {
208 Ok(Literal::Real(exponential))
209 }
210 )
211 }
212 )
213);
214
215pub enum StringError {
217 TooShort,
219 InvalidOpeningCharacter,
221 InvalidClosingCharacter,
223 InvalidEncoding,
225 InvalidDelimiterIdentifier
227}
228
229named!(
230 pub string<Literal>,
231 alt!(
232 string_single_quoted
233 | string_nowdoc
234 )
235);
236
237fn string_single_quoted(input: &[u8]) -> Result<&[u8], Literal> {
238 let input_length = input.len();
239
240 if input_length < 2 {
241 return Result::Error(Error::Code(ErrorKind::Custom(StringError::TooShort as u32)));
242 }
243
244 if input[0] == 'b' as u8 || input[0] == 'B' as u8 {
245 if input_length < 3 {
246 return Result::Error(Error::Code(ErrorKind::Custom(StringError::TooShort as u32)));
247 } else if input[1] != '\'' as u8 {
248 return Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidOpeningCharacter as u32)));
249 } else {
250 return string_single_quoted(&input[1..]);
251 }
252 } else if input[0] != '\'' as u8 {
253 return Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidOpeningCharacter as u32)));
254 }
255
256 let mut output = Vec::new();
257 let mut offset = 1;
258 let mut iterator = input[offset..].iter().enumerate();
259
260 while let Some((index, item)) = iterator.next() {
261 if *item == '\\' as u8 {
262 if let Some((next_index, next_item)) = iterator.next() {
263 if *next_item == '\'' as u8 ||
264 *next_item == '\\' as u8 {
265 output.extend(&input[offset..index + 1]);
266 offset = next_index + 1;
267 }
268 } else {
269 return Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidClosingCharacter as u32)));
270 }
271 } else if *item == '\'' as u8 {
272 output.extend(&input[offset..index + 1]);
273
274 return Result::Done(&input[index + 2..], Literal::String(output));
275 }
276 }
277
278 Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidClosingCharacter as u32)))
279}
280
281const STRING_NOWDOC_OPENING: &'static [u8] = &['<' as u8, '<' as u8, '<' as u8];
282
283fn string_nowdoc(input: &[u8]) -> Result<&[u8], Literal> {
284 let input_length = input.len();
285
286 if input_length < 9 {
288 return Result::Error(Error::Code(ErrorKind::Custom(StringError::TooShort as u32)));
289 }
290
291 if input[0] == 'b' as u8 || input[0] == 'B' as u8 {
292 if input_length < 10 {
293 return Result::Error(Error::Code(ErrorKind::Custom(StringError::TooShort as u32)));
294 } else if false == input[1..].starts_with(STRING_NOWDOC_OPENING) {
295 return Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidOpeningCharacter as u32)));
296 } else {
297 return string_nowdoc(&input[1..]);
298 }
299 } else if false == input.starts_with(STRING_NOWDOC_OPENING) {
300 return Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidOpeningCharacter as u32)));
301 }
302
303 let mut offset = 3;
304
305 for item in input[offset..].iter() {
306 if *item != ' ' as u8 && *item != '\t' as u8 {
307 break;
308 }
309
310 offset += 1;
311 }
312
313 if input[offset] != '\'' as u8 {
314 return Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidOpeningCharacter as u32)));
315 }
316
317 offset += 1;
318
319 let name;
320 let next_input;
321
322 if let Result::Done(i, n) = tokens::name(&input[offset..]) {
323 name = n;
324 next_input = i;
325 } else {
326 return Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidDelimiterIdentifier as u32)))
327 }
328
329 let next_input_length = next_input.len();
330 let name_length = name.len();
331
332 if next_input_length < 3 + name_length || next_input[0] != '\'' as u8 || next_input[1] != '\n' as u8 {
333 if next_input[1] != '\r' as u8 || next_input[2] != '\n' as u8 {
334 return Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidOpeningCharacter as u32)));
335 }
336 }
337
338 if next_input[1] == '\r' as u8 {
339 offset = 2;
340 } else {
341 offset = 1;
342 }
343
344 for (index, item) in next_input[offset..].iter().enumerate() {
345 if *item == '\n' as u8 {
346 if !next_input[offset + index + 1..].starts_with(name) {
347 continue;
348 }
349
350 let mut lookahead_offset = offset + index + name_length + 1;
351
352 if lookahead_offset >= next_input_length {
353 return Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidClosingCharacter as u32)));
354 }
355
356 if next_input[lookahead_offset] == ';' as u8 {
357 lookahead_offset += 1;
358 }
359
360 if lookahead_offset >= next_input_length {
361 return Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidClosingCharacter as u32)));
362 }
363
364 let mut ending_offset = 0;
365
366 if next_input[lookahead_offset] == '\r' as u8 {
367 if lookahead_offset + 1 >= next_input_length {
368 return Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidClosingCharacter as u32)));
369 }
370
371 ending_offset = 1;
372 lookahead_offset += 1;
373 }
374
375 if next_input[lookahead_offset] == '\n' as u8 {
376 if index == 0 {
377 return Result::Done(
378 &next_input[lookahead_offset + 1..],
379 Literal::String(Vec::new())
380 );
381 }
382
383 return Result::Done(
384 &next_input[lookahead_offset + 1..],
385 Literal::String(next_input[offset + 1..offset - ending_offset + index].to_vec())
386 );
387 }
388 }
389 }
390
391 Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidClosingCharacter as u32)))
392}
393
394
395#[cfg(test)]
396mod tests {
397 use super::{
398 StringError,
399 binary,
400 boolean,
401 decimal,
402 exponential,
403 hexadecimal,
404 integer,
405 literal,
406 null,
407 octal,
408 string,
409 string_nowdoc,
410 string_single_quoted
411 };
412 use super::super::super::ast::Literal;
413 use super::super::super::internal::{
414 Error,
415 ErrorKind,
416 Result
417 };
418
419 #[test]
420 fn case_null() {
421 let input = b"null";
422 let output = Result::Done(&b""[..], Literal::Null);
423
424 assert_eq!(null(input), output);
425 assert_eq!(literal(input), output);
426 }
427
428 #[test]
429 fn case_null_case_insensitive() {
430 let input = b"NuLl";
431 let output = Result::Done(&b""[..], Literal::Null);
432
433 assert_eq!(null(input), output);
434 assert_eq!(literal(input), output);
435 }
436
437 #[test]
438 fn case_boolean_true() {
439 let input = b"true";
440 let output = Result::Done(&b""[..], Literal::Boolean(true));
441
442 assert_eq!(boolean(input), output);
443 assert_eq!(literal(input), output);
444 }
445
446 #[test]
447 fn case_boolean_true_case_insensitive() {
448 let input = b"TrUe";
449 let output = Result::Done(&b""[..], Literal::Boolean(true));
450
451 assert_eq!(boolean(input), output);
452 assert_eq!(literal(input), output);
453 }
454
455 #[test]
456 fn case_boolean_false() {
457 let input = b"false";
458 let output = Result::Done(&b""[..], Literal::Boolean(false));
459
460 assert_eq!(boolean(input), output);
461 assert_eq!(literal(input), output);
462 }
463
464 #[test]
465 fn case_boolean_false_case_insensitive() {
466 let input = b"FaLsE";
467 let output = Result::Done(&b""[..], Literal::Boolean(false));
468
469 assert_eq!(boolean(input), output);
470 assert_eq!(literal(input), output);
471 }
472
473 #[test]
474 fn case_binary_lowercase_b() {
475 let input = b"0b101010";
476 let output = Result::Done(&b""[..], Literal::Integer(42i64));
477
478 assert_eq!(binary(input), output);
479 assert_eq!(integer(input), output);
480 assert_eq!(literal(input), output);
481 }
482
483 #[test]
484 fn case_binary_uppercase_b() {
485 let input = b"0B101010";
486 let output = Result::Done(&b""[..], Literal::Integer(42i64));
487
488 assert_eq!(binary(input), output);
489 assert_eq!(integer(input), output);
490 assert_eq!(literal(input), output);
491 }
492
493 #[test]
494 fn case_binary_maximum_integer_value() {
495 let input = b"0b111111111111111111111111111111111111111111111111111111111111111";
496 let output = Result::Done(&b""[..], Literal::Integer(::std::i64::MAX));
497
498 assert_eq!(binary(input), output);
499 assert_eq!(integer(input), output);
500 assert_eq!(literal(input), output);
501 }
502
503 #[test]
504 fn case_invalid_binary_overflow() {
505 let input = b"0b1000000000000000000000000000000000000000000000000000000000000000";
506 let output = Result::Done(&b"b1000000000000000000000000000000000000000000000000000000000000000"[..], Literal::Integer(0i64));
507
508 assert_eq!(binary(input), Result::Error(Error::Position(ErrorKind::MapRes, &input[..])));
509 assert_eq!(integer(input), output);
510 assert_eq!(literal(input), output);
511 }
512
513 #[test]
514 fn case_invalid_binary_no_number() {
515 let input = b"0b";
516 let output = Result::Done(&b"b"[..], Literal::Integer(0i64));
517
518 assert_eq!(binary(input), Result::Error(Error::Position(ErrorKind::MapRes, &b"0b"[..])));
519 assert_eq!(integer(input), output);
520 assert_eq!(literal(input), output);
521 }
522
523 #[test]
524 fn case_invalid_binary_not_starting_by_zero_b() {
525 let input = b"1";
526 let output = Result::Done(&b""[..], Literal::Integer(1i64));
527
528 assert_eq!(binary(input), Result::Error(Error::Position(ErrorKind::Tag, &b"1"[..])));
529 assert_eq!(integer(input), output);
530 assert_eq!(literal(input), output);
531 }
532
533 #[test]
534 fn case_invalid_binary_not_in_base() {
535 let input = b"0b120";
536 let output = Result::Done(&b"20"[..], Literal::Integer(1i64));
537
538 assert_eq!(binary(input), output);
539 assert_eq!(integer(input), output);
540 assert_eq!(literal(input), output);
541 }
542
543 #[test]
544 fn case_octal() {
545 let input = b"052";
546 let output = Result::Done(&b""[..], Literal::Integer(42i64));
547
548 assert_eq!(octal(input), output);
549 assert_eq!(integer(input), output);
550 assert_eq!(literal(input), output);
551 }
552
553 #[test]
554 fn case_octal_zero() {
555 let input = b"0";
556 let output = Result::Done(&b""[..], Literal::Integer(0i64));
557
558 assert_eq!(octal(input), output);
559 assert_eq!(integer(input), output);
560 assert_eq!(literal(input), output);
561 }
562
563 #[test]
564 fn case_octal_maximum_integer_value() {
565 let input = b"0777777777777777777777";
566 let output = Result::Done(&b""[..], Literal::Integer(::std::i64::MAX));
567
568 assert_eq!(octal(input), output);
569 assert_eq!(integer(input), output);
570 assert_eq!(literal(input), output);
571 }
572
573 #[test]
574 fn case_invalid_octal_overflow() {
575 let input = b"01000000000000000000000";
576 let output = Result::Error(Error::Position(ErrorKind::Alt, &b"01000000000000000000000"[..]));
577
578 assert_eq!(octal(input), Result::Error(Error::Position(ErrorKind::MapRes, &b"01000000000000000000000"[..])));
579 assert_eq!(integer(input), output);
580 assert_eq!(literal(input), output);
581 }
582
583 #[test]
584 fn case_invalid_octal_not_starting_by_zero() {
585 let input = b"7";
586 let output = Result::Done(&b""[..], Literal::Integer(7i64));
587
588 assert_eq!(octal(input), Result::Error(Error::Position(ErrorKind::Tag, &b"7"[..])));
589 assert_eq!(integer(input), output);
590 assert_eq!(literal(input), output);
591 }
592
593 #[test]
594 fn case_invalid_octal_not_in_base() {
595 let input = b"8";
596 let output = Result::Done(&b""[..], Literal::Integer(8));
597
598 assert_eq!(octal(input), Result::Error(Error::Position(ErrorKind::Tag, &b"8"[..])));
599 assert_eq!(integer(input), output);
600 assert_eq!(literal(input), output);
601 }
602
603 #[test]
604 fn case_decimal_one_digit() {
605 let input = b"7";
606 let output = Result::Done(&b""[..], Literal::Integer(7i64));
607
608 assert_eq!(decimal(input), output);
609 assert_eq!(integer(input), output);
610 assert_eq!(literal(input), output);
611 }
612
613 #[test]
614 fn case_decimal_many_digits() {
615 let input = b"42";
616 let output = Result::Done(&b""[..], Literal::Integer(42i64));
617
618 assert_eq!(decimal(input), output);
619 assert_eq!(integer(input), output);
620 assert_eq!(literal(input), output);
621 }
622
623 quickcheck! {
624 fn case_decimal_random(input: u32) -> bool {
625 let input = input * 2 + 1;
626 let string = input.to_string();
627 let bytes = string.as_bytes();
628
629 match decimal(bytes) {
630 Result::Done(_, Literal::Integer(output)) => {
631 input == output as u32
632 },
633
634 _ => {
635 false
636 }
637 }
638 }
639 }
640
641 #[test]
642 fn case_decimal_plus() {
643 let input = b"42+";
644 let output = Result::Done(&b"+"[..], Literal::Integer(42i64));
645
646 assert_eq!(decimal(input), output);
647 assert_eq!(integer(input), output);
648 assert_eq!(literal(input), output);
649 }
650
651 #[test]
652 fn case_decimal_maximum_integer_value() {
653 let input = b"9223372036854775807";
654 let output = Result::Done(&b""[..], Literal::Integer(::std::i64::MAX));
655
656 assert_eq!(decimal(input), output);
657 assert_eq!(integer(input), output);
658 assert_eq!(literal(input), output);
659 }
660
661 #[test]
662 fn case_decimal_overflow_to_real() {
663 let input = b"9223372036854775808";
664 let output = Result::Done(&b""[..], Literal::Real(9223372036854775808f64));
665
666 assert_eq!(decimal(input), output);
667 assert_eq!(integer(input), output);
668 assert_eq!(literal(input), output);
669 }
670
671 #[test]
672 fn case_decimal_maximum_real_value() {
673 let input = b"179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
674 let output = Result::Done(&b""[..], Literal::Real(::std::f64::MAX));
675
676 assert_eq!(decimal(input), output);
677 assert_eq!(integer(input), output);
678 assert_eq!(literal(input), output);
679 }
680
681 #[test]
682 fn case_invalid_decimal_overflow_to_infinity() {
683 let input = b"1797693134862315700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
684 let output = Result::Done(&b""[..], Literal::Real(::std::f64::INFINITY));
685
686 assert_eq!(decimal(input), output);
687 assert_eq!(integer(input), output);
688 assert_eq!(literal(input), output);
689 }
690
691 #[test]
692 fn case_hexadecimal_lowercase_x() {
693 let input = b"0x2a";
694 let output = Result::Done(&b""[..], Literal::Integer(42i64));
695
696 assert_eq!(hexadecimal(input), output);
697 assert_eq!(integer(input), output);
698 assert_eq!(literal(input), output);
699 }
700
701 #[test]
702 fn case_hexadecimal_uppercase_x() {
703 let input = b"0X2a";
704 let output = Result::Done(&b""[..], Literal::Integer(42i64));
705
706 assert_eq!(hexadecimal(input), output);
707 assert_eq!(integer(input), output);
708 assert_eq!(literal(input), output);
709 }
710
711 #[test]
712 fn case_hexadecimal_uppercase_alpha() {
713 let input = b"0x2A";
714 let output = Result::Done(&b""[..], Literal::Integer(42i64));
715
716 assert_eq!(hexadecimal(input), output);
717 assert_eq!(integer(input), output);
718 assert_eq!(literal(input), output);
719 }
720
721 #[test]
722 fn case_invalid_hexadecimal_no_number() {
723 let input = b"0x";
724 let output = Result::Done(&b"x"[..], Literal::Integer(0i64));
725
726 assert_eq!(hexadecimal(input), Result::Error(Error::Position(ErrorKind::HexDigit, &b""[..])));
727 assert_eq!(integer(input), output);
728 assert_eq!(literal(input), output);
729 }
730
731 #[test]
732 fn case_invalid_hexadecimal_not_in_base() {
733 let input = b"0xg";
734 let output = Result::Done(&b"xg"[..], Literal::Integer(0i64));
735
736 assert_eq!(hexadecimal(input), Result::Error(Error::Position(ErrorKind::HexDigit, &b"g"[..])));
737 assert_eq!(integer(input), output);
738 assert_eq!(literal(input), output);
739 }
740
741 #[test]
742 fn case_hexadecimal_maximum_integer_value() {
743 let input = b"0x7fffffffffffffff";
744 let output = Result::Done(&b""[..], Literal::Integer(::std::i64::MAX));
745
746 assert_eq!(hexadecimal(input), output);
747 assert_eq!(integer(input), output);
748 assert_eq!(literal(input), output);
749 }
750
751 #[test]
752 fn case_invalid_hexadecimal_overflow() {
753 let input = b"0x8000000000000000";
754 let output = Result::Done(&b"x8000000000000000"[..], Literal::Integer(0i64));
755
756 assert_eq!(hexadecimal(input), Result::Error(Error::Position(ErrorKind::MapRes, &b"0x8000000000000000"[..])));
757 assert_eq!(integer(input), output);
758 assert_eq!(literal(input), output);
759 }
760
761 #[test]
762 fn case_exponential() {
763 let input = b"123.456e+78";
764 let output = Result::Done(&b""[..], Literal::Real(123.456e78f64));
765
766 assert_eq!(exponential(input), output);
767 assert_eq!(literal(input), output);
768 }
769
770 #[test]
771 fn case_exponential_only_with_rational_and_fractional_part() {
772 let input = b"123.456";
773 let output = Result::Done(&b""[..], Literal::Real(123.456f64));
774
775 assert_eq!(exponential(input), output);
776 assert_eq!(literal(input), output);
777 }
778
779 #[test]
780 fn case_exponential_only_with_rational_part() {
781 let input = b"123.";
782 let output = Result::Done(&b""[..], Literal::Real(123.0f64));
783
784 assert_eq!(exponential(input), output);
785 assert_eq!(literal(input), output);
786 }
787
788 #[test]
789 fn case_exponential_only_with_fractional_part() {
790 let input = b".456";
791 let output = Result::Done(&b""[..], Literal::Real(0.456f64));
792
793 assert_eq!(exponential(input), output);
794 assert_eq!(literal(input), output);
795 }
796
797 #[test]
798 fn case_exponential_only_with_rational_and_exponent_part_with_lowercase_e() {
799 let input = b"123.e78";
800 let output = Result::Done(&b""[..], Literal::Real(123e78f64));
801
802 assert_eq!(exponential(input), output);
803 assert_eq!(literal(input), output);
804 }
805
806 #[test]
807 fn case_exponential_only_with_integer_rational_and_exponent_part() {
808 let input = b"123e78";
809 let output = Result::Done(&b""[..], Literal::Real(123e78f64));
810
811 assert_eq!(exponential(input), output);
812 assert_eq!(literal(input), output);
813 }
814
815 #[test]
816 fn case_exponential_only_with_rational_and_exponent_part_with_uppercase_e() {
817 let input = b"123.E78";
818 let output = Result::Done(&b""[..], Literal::Real(123e78f64));
819
820 assert_eq!(exponential(input), output);
821 assert_eq!(literal(input), output);
822 }
823
824 #[test]
825 fn case_exponential_only_with_rational_and_unsigned_exponent_part() {
826 let input = b"123.e78";
827 let output = Result::Done(&b""[..], Literal::Real(123e78f64));
828
829 assert_eq!(exponential(input), output);
830 assert_eq!(literal(input), output);
831 }
832
833 #[test]
834 fn case_exponential_only_with_rational_and_positive_exponent_part() {
835 let input = b"123.e+78";
836 let output = Result::Done(&b""[..], Literal::Real(123e78f64));
837
838 assert_eq!(exponential(input), output);
839 assert_eq!(literal(input), output);
840 }
841
842 #[test]
843 fn case_exponential_only_with_rational_and_negative_exponent_part() {
844 let input = b"123.e-78";
845 let output = Result::Done(&b""[..], Literal::Real(123e-78f64));
846
847 assert_eq!(exponential(input), output);
848 assert_eq!(literal(input), output);
849 }
850
851 #[test]
852 fn case_exponential_only_with_rational_and_negative_zero_exponent_part() {
853 let input = b"123.e-0";
854 let output = Result::Done(&b""[..], Literal::Real(123f64));
855
856 assert_eq!(exponential(input), output);
857 assert_eq!(literal(input), output);
858 }
859
860 #[test]
861 fn case_exponential_missing_exponent_part() {
862 let input = b".7e";
863 let output = Result::Done(&b"e"[..], Literal::Real(0.7f64));
864
865 assert_eq!(exponential(input), output);
866 assert_eq!(literal(input), output);
867 }
868
869 #[test]
870 fn case_invalid_exponential_only_the_dot() {
871 let input = b".";
872
873 assert_eq!(exponential(input), Result::Error(Error::Code(ErrorKind::RegexpFind)));
874 assert_eq!(literal(input), Result::Error(Error::Position(ErrorKind::Alt, &b"."[..])));
875 }
876
877 #[test]
878 fn case_string_single_quoted() {
879 let input = b"'foobar'";
880 let output = Result::Done(&b""[..], Literal::String(b"foobar".to_vec()));
881
882 assert_eq!(string_single_quoted(input), output);
883 assert_eq!(string(input), output);
884 assert_eq!(literal(input), output);
885 }
886
887 #[test]
888 fn case_string_single_quoted_escaped_quote() {
889 let input = b"'foo\\'bar'";
890 let output = Result::Done(&b""[..], Literal::String(b"foo'bar".to_vec()));
891
892 assert_eq!(string_single_quoted(input), output);
893 assert_eq!(string(input), output);
894 assert_eq!(literal(input), output);
895 }
896
897 #[test]
898 fn case_string_single_quoted_escaped_backslash() {
899 let input = b"'foo\\\\bar'";
900 let output = Result::Done(&b""[..], Literal::String(b"foo\\bar".to_vec()));
901
902 assert_eq!(string_single_quoted(input), output);
903 assert_eq!(string(input), output);
904 assert_eq!(literal(input), output);
905 }
906
907 #[test]
908 fn case_string_single_quoted_escaped_any() {
909 let input = b"'foo\\nbar'";
910 let output = Result::Done(&b""[..], Literal::String(b"foo\\nbar".to_vec()));
911
912 assert_eq!(string_single_quoted(input), output);
913 assert_eq!(string(input), output);
914 assert_eq!(literal(input), output);
915 }
916
917 #[test]
918 fn case_string_single_quoted_escaped_many() {
919 let input = b"'\\'f\\oo\\\\bar\\\\'";
920 let output = Result::Done(&b""[..], Literal::String(b"'f\\oo\\bar\\".to_vec()));
921
922 assert_eq!(string_single_quoted(input), output);
923 assert_eq!(string(input), output);
924 assert_eq!(literal(input), output);
925 }
926
927 #[test]
928 fn case_string_single_quoted_empty() {
929 let input = b"''";
930 let output = Result::Done(&b""[..], Literal::String(Vec::new()));
931
932 assert_eq!(string_single_quoted(input), output);
933 assert_eq!(string(input), output);
934 assert_eq!(literal(input), output);
935 }
936
937 #[test]
938 fn case_string_binary_single_quoted() {
939 let input = b"b'foobar'";
940 let output = Result::Done(&b""[..], Literal::String(b"foobar".to_vec()));
941
942 assert_eq!(string_single_quoted(input), output);
943 assert_eq!(string(input), output);
944 assert_eq!(literal(input), output);
945 }
946
947 #[test]
948 fn case_string_binary_uppercase_single_quoted() {
949 let input = b"B'foobar'";
950 let output = Result::Done(&b""[..], Literal::String(b"foobar".to_vec()));
951
952 assert_eq!(string_single_quoted(input), output);
953 assert_eq!(string(input), output);
954 assert_eq!(literal(input), output);
955 }
956
957 #[test]
958 fn case_string_binary_single_quoted_escaped_many() {
959 let input = b"b'\\'f\\oo\\\\bar'";
960 let output = Result::Done(&b""[..], Literal::String(b"'f\\oo\\bar".to_vec()));
961
962 assert_eq!(string_single_quoted(input), output);
963 assert_eq!(string(input), output);
964 assert_eq!(literal(input), output);
965 }
966
967 #[test]
968 fn case_invalid_string_single_quoted_too_short() {
969 let input = b"'";
970 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
971
972 assert_eq!(string_single_quoted(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::TooShort as u32))));
973 assert_eq!(string(input), output);
974 assert_eq!(literal(input), output);
975 }
976
977 #[test]
978 fn case_invalid_string_single_quoted_opening_character() {
979 let input = b"foobar'";
980 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
981
982 assert_eq!(string_single_quoted(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidOpeningCharacter as u32))));
983 assert_eq!(string(input), output);
984 assert_eq!(literal(input), output);
985 }
986
987 #[test]
988 fn case_invalid_string_single_quoted_closing_character() {
989 let input = b"'foobar";
990 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
991
992 assert_eq!(string_single_quoted(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidClosingCharacter as u32))));
993 assert_eq!(string(input), output);
994 assert_eq!(literal(input), output);
995 }
996
997 #[test]
998 fn case_invalid_string_single_quoted_closing_character_is_a_backslash() {
999 let input = b"'foobar\\";
1000 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1001
1002 assert_eq!(string_single_quoted(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidClosingCharacter as u32))));
1003 assert_eq!(string(input), output);
1004 assert_eq!(literal(input), output);
1005 }
1006
1007 #[test]
1008 fn case_invalid_string_binary_single_quoted_too_short() {
1009 let input = b"b'";
1010 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1011
1012 assert_eq!(string_single_quoted(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::TooShort as u32))));
1013 assert_eq!(string(input), output);
1014 assert_eq!(literal(input), output);
1015 }
1016
1017 #[test]
1018 fn case_invalid_string_binary_uppercase_single_quoted_too_short() {
1019 let input = b"B'";
1020 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1021
1022 assert_eq!(string_single_quoted(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::TooShort as u32))));
1023 assert_eq!(string(input), output);
1024 assert_eq!(literal(input), output);
1025 }
1026
1027 #[test]
1028 fn case_invalid_string_binary_single_quoted_opening_character() {
1029 let input = b"bb'";
1030 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1031
1032 assert_eq!(string_single_quoted(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidOpeningCharacter as u32))));
1033 assert_eq!(string(input), output);
1034 assert_eq!(literal(input), output);
1035 }
1036
1037 #[test]
1038 fn case_string_nowdoc() {
1039 let input = b"<<<'FOO'\nhello \n world \nFOO;\n";
1040 let output = Result::Done(&b""[..], Literal::String(b"hello \n world ".to_vec()));
1041
1042 assert_eq!(string_nowdoc(input), output);
1043 assert_eq!(string(input), output);
1044 assert_eq!(literal(input), output);
1045 }
1046
1047 #[test]
1048 fn case_string_nowdoc_crlf() {
1049 let input = b"<<<'FOO'\r\nhello \r\n world \r\nFOO;\r\n";
1050 let output = Result::Done(&b""[..], Literal::String(b"hello \r\n world ".to_vec()));
1051
1052 assert_eq!(string_nowdoc(input), output);
1053 assert_eq!(string(input), output);
1054 assert_eq!(literal(input), output);
1055 }
1056
1057 #[test]
1058 fn case_string_nowdoc_without_semi_colon() {
1059 let input = b"<<<'FOO'\nhello \n world \nFOO\n";
1060 let output = Result::Done(&b""[..], Literal::String(b"hello \n world ".to_vec()));
1061
1062 assert_eq!(string_nowdoc(input), output);
1063 assert_eq!(string(input), output);
1064 assert_eq!(literal(input), output);
1065 }
1066
1067 #[test]
1068 fn case_string_nowdoc_without_semi_colon_crlf() {
1069 let input = b"<<<'FOO'\r\nhello \r\n world \r\nFOO\r\n";
1070 let output = Result::Done(&b""[..], Literal::String(b"hello \r\n world ".to_vec()));
1071
1072 assert_eq!(string_nowdoc(input), output);
1073 assert_eq!(string(input), output);
1074 assert_eq!(literal(input), output);
1075 }
1076
1077 #[test]
1078 fn case_string_nowdoc_empty() {
1079 let input = b"<<<'FOO'\nFOO\n";
1080 let output = Result::Done(&b""[..], Literal::String(Vec::new()));
1081
1082 assert_eq!(string_nowdoc(input), output);
1083 assert_eq!(string(input), output);
1084 assert_eq!(literal(input), output);
1085 }
1086
1087 #[test]
1088 fn case_string_nowdoc_empty_crlf() {
1089 let input = b"<<<'FOO'\r\nFOO\r\n";
1090 let output = Result::Done(&b""[..], Literal::String(Vec::new()));
1091
1092 assert_eq!(string_nowdoc(input), output);
1093 assert_eq!(string(input), output);
1094 assert_eq!(literal(input), output);
1095 }
1096
1097 #[test]
1098 fn case_string_nowdoc_with_whitespaces_before_identifier() {
1099 let input = b"<<< \t 'FOO'\nhello \n world \nFOO\n";
1100 let output = Result::Done(&b""[..], Literal::String(b"hello \n world ".to_vec()));
1101
1102 assert_eq!(string_nowdoc(input), output);
1103 assert_eq!(string(input), output);
1104 assert_eq!(literal(input), output);
1105 }
1106
1107 #[test]
1108 fn case_string_nowdoc_with_whitespaces_before_identifier_crlf() {
1109 let input = b"<<< \t 'FOO'\r\nhello \r\n world \r\nFOO\r\n";
1110 let output = Result::Done(&b""[..], Literal::String(b"hello \r\n world ".to_vec()));
1111
1112 assert_eq!(string_nowdoc(input), output);
1113 assert_eq!(string(input), output);
1114 assert_eq!(literal(input), output);
1115 }
1116
1117 #[test]
1118 fn case_string_binary_nowdoc() {
1119 let input = b"b<<<'FOO'\nhello \n world \nFOO\n";
1120 let output = Result::Done(&b""[..], Literal::String(b"hello \n world ".to_vec()));
1121
1122 assert_eq!(string_nowdoc(input), output);
1123 assert_eq!(string(input), output);
1124 assert_eq!(literal(input), output);
1125 }
1126
1127 #[test]
1128 fn case_string_binary_nowdoc_crlf() {
1129 let input = b"b<<<'FOO'\r\nhello \r\n world \r\nFOO\r\n";
1130 let output = Result::Done(&b""[..], Literal::String(b"hello \r\n world ".to_vec()));
1131
1132 assert_eq!(string_nowdoc(input), output);
1133 assert_eq!(string(input), output);
1134 assert_eq!(literal(input), output);
1135 }
1136
1137 #[test]
1138 fn case_string_binary_uppercase_nowdoc() {
1139 let input = b"B<<<'FOO'\nhello \n world \nFOO\n";
1140 let output = Result::Done(&b""[..], Literal::String(b"hello \n world ".to_vec()));
1141
1142 assert_eq!(string_nowdoc(input), output);
1143 assert_eq!(string(input), output);
1144 assert_eq!(literal(input), output);
1145 }
1146
1147 #[test]
1148 fn case_string_binary_uppercase_nowdoc_crlf() {
1149 let input = b"B<<<'FOO'\r\nhello \r\n world \r\nFOO\r\n";
1150 let output = Result::Done(&b""[..], Literal::String(b"hello \r\n world ".to_vec()));
1151
1152 assert_eq!(string_nowdoc(input), output);
1153 assert_eq!(string(input), output);
1154 assert_eq!(literal(input), output);
1155 }
1156
1157 #[test]
1158 fn case_invalid_string_nowdoc_too_short() {
1159 let input = b"<<<'A'\nA";
1160 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1161
1162 assert_eq!(string_nowdoc(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::TooShort as u32))));
1163 assert_eq!(string(input), output);
1164 assert_eq!(literal(input), output);
1165 }
1166
1167 #[test]
1168 fn case_invalid_string_nowdoc_opening_character() {
1169 let input = b"<<FOO'\nhello \n world \nFOO\n";
1170 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1171
1172 assert_eq!(string_nowdoc(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidOpeningCharacter as u32))));
1173 assert_eq!(string(input), output);
1174 assert_eq!(literal(input), output);
1175 }
1176
1177 #[test]
1178 fn case_invalid_string_nowdoc_opening_character_missing_first_quote() {
1179 let input = b"<<<FOO'\nhello \n world \nFOO\n";
1180 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1181
1182 assert_eq!(string_nowdoc(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidOpeningCharacter as u32))));
1183 assert_eq!(string(input), output);
1184 assert_eq!(literal(input), output);
1185 }
1186
1187 #[test]
1188 fn case_invalid_string_nowdoc_opening_character_missing_second_quote() {
1189 let input = b"<<<'FOO\nhello \n world \nFOO\n";
1190 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1191
1192 assert_eq!(string_nowdoc(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidOpeningCharacter as u32))));
1193 assert_eq!(string(input), output);
1194 assert_eq!(literal(input), output);
1195 }
1196
1197 #[test]
1198 fn case_invalid_string_nowdoc_invalid_identifier() {
1199 let input = b"<<<'42'\nhello \n world \n42\n";
1200 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1201
1202 assert_eq!(string_nowdoc(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidDelimiterIdentifier as u32))));
1203 assert_eq!(string(input), output);
1204 assert_eq!(literal(input), output);
1205 }
1206
1207 #[test]
1208 fn case_invalid_string_nowdoc_partially_invalid_identifier() {
1209 let input = b"<<<'F O O'\nhello \n world \nF O O\n";
1210 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1211
1212 assert_eq!(string_nowdoc(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidOpeningCharacter as u32))));
1213 assert_eq!(string(input), output);
1214 assert_eq!(literal(input), output);
1215 }
1216
1217 #[test]
1218 fn case_invalid_string_nowdoc_opening_character_missing_newline() {
1219 let input = b"<<<'FOO'hello \n world \nFOO\n";
1220 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1221
1222 assert_eq!(string_nowdoc(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidOpeningCharacter as u32))));
1223 assert_eq!(string(input), output);
1224 assert_eq!(literal(input), output);
1225 }
1226
1227 #[test]
1228 fn case_invalid_string_nowdoc_closing_character() {
1229 let input = b"<<<'FOO'\nhello \n world \nFO;\n";
1230 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1231
1232 assert_eq!(string_nowdoc(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidClosingCharacter as u32))));
1233 assert_eq!(string(input), output);
1234 assert_eq!(literal(input), output);
1235 }
1236
1237 #[test]
1238 fn case_invalid_string_nowdoc_closing_character_no_semi_colon_no_newline() {
1239 let input = b"<<<'FOO'\nhello \n world \nFOO";
1240 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1241
1242 assert_eq!(string_nowdoc(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidClosingCharacter as u32))));
1243 assert_eq!(string(input), output);
1244 assert_eq!(literal(input), output);
1245 }
1246
1247 #[test]
1248 fn case_invalid_string_nowdoc_closing_character_no_semi_colon_no_newline_crlf() {
1249 let input = b"<<<'FOO'\r\nhello \r\n world \r\nFOO";
1250 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1251
1252 assert_eq!(string_nowdoc(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidClosingCharacter as u32))));
1253 assert_eq!(string(input), output);
1254 assert_eq!(literal(input), output);
1255 }
1256
1257 #[test]
1258 fn case_invalid_string_nowdoc_closing_character_no_newline() {
1259 let input = b"<<<'FOO'\nhello \n world \nFOO;";
1260 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1261
1262 assert_eq!(string_nowdoc(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidClosingCharacter as u32))));
1263 assert_eq!(string(input), output);
1264 assert_eq!(literal(input), output);
1265 }
1266
1267 #[test]
1268 fn case_invalid_string_nowdoc_closing_character_no_newline_crlf() {
1269 let input = b"<<<'FOO'\r\nhello \r\n world \r\nFOO;";
1270 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1271
1272 assert_eq!(string_nowdoc(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidClosingCharacter as u32))));
1273 assert_eq!(string(input), output);
1274 assert_eq!(literal(input), output);
1275 }
1276
1277 #[test]
1278 fn case_invalid_string_nowdoc_closing_character_missing_lf_in_crlf() {
1279 let input = b"<<<'FOO'\r\nhello \r\n world \r\nFOO\r";
1280 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1281
1282 assert_eq!(string_nowdoc(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidClosingCharacter as u32))));
1283 assert_eq!(string(input), output);
1284 assert_eq!(literal(input), output);
1285 }
1286
1287 #[test]
1288 fn case_invalid_string_binary_nowdoc_too_short() {
1289 let input = b"b<<<'A'\nA";
1290 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1291
1292 assert_eq!(string_nowdoc(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::TooShort as u32))));
1293 assert_eq!(string(input), output);
1294 assert_eq!(literal(input), output);
1295 }
1296
1297 #[test]
1298 fn case_invalid_string_binary_nowdoc_opening_character() {
1299 let input = b"b<<FOO'\nhello \n world \nFOO\n";
1300 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1301
1302 assert_eq!(string_nowdoc(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidOpeningCharacter as u32))));
1303 assert_eq!(string(input), output);
1304 assert_eq!(literal(input), output);
1305 }
1306
1307 #[test]
1308 fn case_invalid_string_binary_nowdoc_opening_character_missing_first_quote() {
1309 let input = b"b<<<FOO'\nhello \n world \nFOO\n";
1310 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1311
1312 assert_eq!(string_nowdoc(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidOpeningCharacter as u32))));
1313 assert_eq!(string(input), output);
1314 assert_eq!(literal(input), output);
1315 }
1316
1317 #[test]
1318 fn case_invalid_string_binary_nowdoc_opening_character_missing_second_quote() {
1319 let input = b"b<<<'FOO\nhello \n world \nFOO\n";
1320 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1321
1322 assert_eq!(string_nowdoc(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidOpeningCharacter as u32))));
1323 assert_eq!(string(input), output);
1324 assert_eq!(literal(input), output);
1325 }
1326
1327 #[test]
1328 fn case_invalid_string_binary_uppercase_nowdoc_too_short() {
1329 let input = b"B<<<'A'\nA";
1330 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1331
1332 assert_eq!(string_nowdoc(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::TooShort as u32))));
1333 assert_eq!(string(input), output);
1334 assert_eq!(literal(input), output);
1335 }
1336
1337 #[test]
1338 fn case_invalid_string_binary_uppercase_nowdoc_opening_character() {
1339 let input = b"B<<FOO'\nhello \n world \nFOO\n";
1340 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1341
1342 assert_eq!(string_nowdoc(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidOpeningCharacter as u32))));
1343 assert_eq!(string(input), output);
1344 assert_eq!(literal(input), output);
1345 }
1346
1347 #[test]
1348 fn case_invalid_string_binary_uppercase_nowdoc_opening_character_missing_first_quote() {
1349 let input = b"B<<<FOO'\nhello \n world \nFOO\n";
1350 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1351
1352 assert_eq!(string_nowdoc(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidOpeningCharacter as u32))));
1353 assert_eq!(string(input), output);
1354 assert_eq!(literal(input), output);
1355 }
1356
1357 #[test]
1358 fn case_invalid_string_binary_uppercase_nowdoc_opening_character_missing_second_quote() {
1359 let input = b"B<<<'FOO\nhello \n world \nFOO\n";
1360 let output = Result::Error(Error::Position(ErrorKind::Alt, &input[..]));
1361
1362 assert_eq!(string_nowdoc(input), Result::Error(Error::Code(ErrorKind::Custom(StringError::InvalidOpeningCharacter as u32))));
1363 assert_eq!(string(input), output);
1364 assert_eq!(literal(input), output);
1365 }
1366}