tagua_parser/rules/
literals.rs

1// Tagua VM
2//
3//
4// New BSD License
5//
6// Copyright © 2016-2016, Ivan Enderlin.
7// All rights reserved.
8//
9// Redistribution and use in source and binary forms, with or without
10// modification, are permitted provided that the following conditions are met:
11//     * Redistributions of source code must retain the above copyright
12//       notice, this list of conditions and the following disclaimer.
13//     * Redistributions in binary form must reproduce the above copyright
14//       notice, this list of conditions and the following disclaimer in the
15//       documentation and/or other materials provided with the distribution.
16//     * Neither the name of the Hoa nor the names of its contributors may be
17//       used to endorse or promote products derived from this software without
18//       specific prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
24// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30// POSSIBILITY OF SUCH DAMAGE.
31
32//! Group of literal rules.
33//!
34//! The list of all literals is provided by the PHP Language Specification in
35//! the [Grammar chapter, Literals
36//! section](https://github.com/php/php-langspec/blob/master/spec/19-grammar.md#literals).
37
38use 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
215/// String errors.
216pub enum StringError {
217    /// The datum starts as a string but is too short to be a string.
218    TooShort,
219    /// The string open character is not correct.
220    InvalidOpeningCharacter,
221    /// The string close character is not correct.
222    InvalidClosingCharacter,
223    /// The string is not correctly encoded (expect UTF-8).
224    InvalidEncoding,
225    /// The string delimiter identifier is syntactically invalid.
226    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    // `<<<'A'\nA\n` is the shortest datum.
287    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}