use super::*;
use snapbox::prelude::*;
use snapbox::str;

use crate::error::ErrMode;
use crate::error::ErrMode::Backtrack;
use crate::error::InputError;
use crate::token::literal;

#[test]
fn test_literal_support_char() {
    assert_eq!(
        literal::<_, &[u8], ErrMode<InputError<_>>>(Caseless('a')).parse_peek(b"ABCxyz"),
        Ok((&b"BCxyz"[..], &b"A"[..]))
    );

    assert_eq!(
        literal::<_, &[u8], ErrMode<InputError<_>>>('a').parse_peek(b"ABCxyz"),
        Err(Backtrack(InputError::at(&b"ABCxyz"[..],)))
    );

    assert_eq!(
        literal::<_, &[u8], ErrMode<InputError<_>>>(Caseless('π')).parse_peek(b"\xCF\x803.14"),
        Ok((&b"3.14"[..], "π".as_bytes()))
    );

    assert_eq!(
        literal::<_, _, ErrMode<InputError<_>>>(Caseless('🧑')).parse_peek("🧑你好"),
        Ok(("你好", "🧑"))
    );

    let mut buffer = [0; 4];
    let input = '\u{241b}'.encode_utf8(&mut buffer);
    assert_eq!(
        literal::<_, &[u8], ErrMode<InputError<_>>>(Caseless('␛')).parse_peek(input.as_bytes()),
        Ok((&b""[..], [226, 144, 155].as_slice()))
    );
}

mod complete {
    use super::*;

    use proptest::prelude::*;

    use crate::combinator::alt;
    use crate::error::ErrMode;
    use crate::error::InputError;
    use crate::prelude::*;
    use crate::stream::ParseSlice;
    use crate::token::none_of;
    use crate::token::one_of;
    use crate::token::take_till;
    #[cfg(feature = "alloc")]
    use alloc::string::String;
    #[cfg(feature = "alloc")]
    use alloc::vec::Vec;

    #[test]
    fn character() {
        let a: &[u8] = b"abcd";
        let b: &[u8] = b"1234";
        let c: &[u8] = b"a123";
        let d: &[u8] = "azé12".as_bytes();
        let e: &[u8] = b" ";
        let f: &[u8] = b" ;";
        //assert_parse!(alpha1::<_, InputError>(a), str![]);
        assert_parse!(
            alpha1.parse_peek(a),
            str![[r#"
Ok(
    (
        [],
        [
            97,
            98,
            99,
            100,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            alpha1.parse_peek(b),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                49,
                50,
                51,
                52,
            ],
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            alpha1.parse_peek(c),
            str![[r#"
Ok(
    (
        [
            49,
            50,
            51,
        ],
        [
            97,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            alpha1.parse_peek(d),
            str![[r#"
Ok(
    (
        [
            195,
            169,
            49,
            50,
        ],
        [
            97,
            122,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            digit1.parse_peek(a),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                97,
                98,
                99,
                100,
            ],
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            digit1.parse_peek(b),
            str![[r#"
Ok(
    (
        [],
        [
            49,
            50,
            51,
            52,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            digit1.parse_peek(c),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                97,
                49,
                50,
                51,
            ],
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            digit1.parse_peek(d),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                97,
                122,
                195,
                169,
                49,
                50,
            ],
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_digit1.parse_peek(a),
            str![[r#"
Ok(
    (
        [],
        [
            97,
            98,
            99,
            100,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_digit1.parse_peek(b),
            str![[r#"
Ok(
    (
        [],
        [
            49,
            50,
            51,
            52,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_digit1.parse_peek(c),
            str![[r#"
Ok(
    (
        [],
        [
            97,
            49,
            50,
            51,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_digit1.parse_peek(d),
            str![[r#"
Ok(
    (
        [
            122,
            195,
            169,
            49,
            50,
        ],
        [
            97,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_digit1.parse_peek(e),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                32,
            ],
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            oct_digit1.parse_peek(a),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                97,
                98,
                99,
                100,
            ],
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            oct_digit1.parse_peek(b),
            str![[r#"
Ok(
    (
        [],
        [
            49,
            50,
            51,
            52,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            oct_digit1.parse_peek(c),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                97,
                49,
                50,
                51,
            ],
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            oct_digit1.parse_peek(d),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                97,
                122,
                195,
                169,
                49,
                50,
            ],
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            alphanumeric1.parse_peek(a),
            str![[r#"
Ok(
    (
        [],
        [
            97,
            98,
            99,
            100,
        ],
    ),
)

"#]]
            .raw()
        );
        //assert_parse!(fix_error!(b,(), alphanumeric), str![]);
        assert_parse!(
            alphanumeric1.parse_peek(c),
            str![[r#"
Ok(
    (
        [],
        [
            97,
            49,
            50,
            51,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            alphanumeric1.parse_peek(d),
            str![[r#"
Ok(
    (
        [
            195,
            169,
            49,
            50,
        ],
        [
            97,
            122,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            space1.parse_peek(e),
            str![[r#"
Ok(
    (
        [],
        [
            32,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            space1.parse_peek(f),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        [
            32,
        ],
    ),
)

"#]]
            .raw()
        );
    }

    #[cfg(feature = "alloc")]
    #[test]
    fn character_s() {
        let a = "abcd";
        let b = "1234";
        let c = "a123";
        let d = "azé12";
        let e = " ";
        assert_parse!(
            alpha1.parse_peek(a),
            str![[r#"
Ok(
    (
        "",
        "abcd",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            alpha1.parse_peek(b),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: "1234",
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            alpha1.parse_peek(c),
            str![[r#"
Ok(
    (
        "123",
        "a",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            alpha1.parse_peek(d),
            str![[r#"
Ok(
    (
        "é12",
        "az",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            digit1.parse_peek(a),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: "abcd",
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            digit1.parse_peek(b),
            str![[r#"
Ok(
    (
        "",
        "1234",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            digit1.parse_peek(c),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: "a123",
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            digit1.parse_peek(d),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: "azé12",
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_digit1.parse_peek(a),
            str![[r#"
Ok(
    (
        "",
        "abcd",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_digit1.parse_peek(b),
            str![[r#"
Ok(
    (
        "",
        "1234",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_digit1.parse_peek(c),
            str![[r#"
Ok(
    (
        "",
        "a123",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_digit1.parse_peek(d),
            str![[r#"
Ok(
    (
        "zé12",
        "a",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_digit1.parse_peek(e),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: " ",
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            oct_digit1.parse_peek(a),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: "abcd",
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            oct_digit1.parse_peek(b),
            str![[r#"
Ok(
    (
        "",
        "1234",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            oct_digit1.parse_peek(c),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: "a123",
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            oct_digit1.parse_peek(d),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: "azé12",
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            alphanumeric1.parse_peek(a),
            str![[r#"
Ok(
    (
        "",
        "abcd",
    ),
)

"#]]
            .raw()
        );
        //assert_parse!(fix_error!(b,(), alphanumeric), str![]);
        assert_parse!(
            alphanumeric1.parse_peek(c),
            str![[r#"
Ok(
    (
        "",
        "a123",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            alphanumeric1.parse_peek(d),
            str![[r#"
Ok(
    (
        "é12",
        "az",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            space1.parse_peek(e),
            str![[r#"
Ok(
    (
        "",
        " ",
    ),
)

"#]]
            .raw()
        );
    }

    use crate::stream::Offset;
    #[test]
    fn offset() {
        let a = &b"abcd;"[..];
        let b = &b"1234;"[..];
        let c = &b"a123;"[..];
        let d = &b" \t;"[..];
        let e = &b" \t\r\n;"[..];
        let f = &b"123abcDEF;"[..];

        match alpha1::<_, InputError<_>>.parse_peek(a) {
            Ok((i, _)) => {
                assert_eq!(i.offset_from(&a) + i.len(), a.len());
            }
            _ => panic!("wrong return type in offset test for alpha"),
        }
        match digit1::<_, InputError<_>>.parse_peek(b) {
            Ok((i, _)) => {
                assert_eq!(i.offset_from(&b) + i.len(), b.len());
            }
            _ => panic!("wrong return type in offset test for digit"),
        }
        match alphanumeric1::<_, InputError<_>>.parse_peek(c) {
            Ok((i, _)) => {
                assert_eq!(i.offset_from(&c) + i.len(), c.len());
            }
            _ => panic!("wrong return type in offset test for alphanumeric"),
        }
        match space1::<_, InputError<_>>.parse_peek(d) {
            Ok((i, _)) => {
                assert_eq!(i.offset_from(&d) + i.len(), d.len());
            }
            _ => panic!("wrong return type in offset test for space"),
        }
        match multispace1::<_, InputError<_>>.parse_peek(e) {
            Ok((i, _)) => {
                assert_eq!(i.offset_from(&e) + i.len(), e.len());
            }
            _ => panic!("wrong return type in offset test for multispace"),
        }
        match hex_digit1::<_, InputError<_>>.parse_peek(f) {
            Ok((i, _)) => {
                assert_eq!(i.offset_from(&f) + i.len(), f.len());
            }
            _ => panic!("wrong return type in offset test for hex_digit"),
        }
        match oct_digit1::<_, InputError<_>>.parse_peek(f) {
            Ok((i, _)) => {
                assert_eq!(i.offset_from(&f) + i.len(), f.len());
            }
            _ => panic!("wrong return type in offset test for oct_digit"),
        }
    }

    #[test]
    fn is_till_line_ending_bytes() {
        let a: &[u8] = b"ab12cd\nefgh";
        assert_parse!(
            till_line_ending.parse_peek(a),
            str![[r#"
Ok(
    (
        [
            10,
            101,
            102,
            103,
            104,
        ],
        [
            97,
            98,
            49,
            50,
            99,
            100,
        ],
    ),
)

"#]]
            .raw()
        );

        let b: &[u8] = b"ab12cd\nefgh\nijkl";
        assert_parse!(
            till_line_ending.parse_peek(b),
            str![[r#"
Ok(
    (
        [
            10,
            101,
            102,
            103,
            104,
            10,
            105,
            106,
            107,
            108,
        ],
        [
            97,
            98,
            49,
            50,
            99,
            100,
        ],
    ),
)

"#]]
            .raw()
        );

        let c: &[u8] = b"ab12cd\r\nefgh\nijkl";
        assert_parse!(
            till_line_ending.parse_peek(c),
            str![[r#"
Ok(
    (
        [
            13,
            10,
            101,
            102,
            103,
            104,
            10,
            105,
            106,
            107,
            108,
        ],
        [
            97,
            98,
            49,
            50,
            99,
            100,
        ],
    ),
)

"#]]
            .raw()
        );

        let d: &[u8] = b"ab12cd";
        assert_parse!(
            till_line_ending.parse_peek(d),
            str![[r#"
Ok(
    (
        [],
        [
            97,
            98,
            49,
            50,
            99,
            100,
        ],
    ),
)

"#]]
            .raw()
        );
    }

    #[test]
    fn is_till_line_ending_str() {
        let f = "βèƒôřè\rÂßÇáƒƭèř";
        assert_parse!(
            till_line_ending.parse_peek(f),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: "\rÂßÇáƒƭèř",
        },
    ),
)

"#]]
            .raw()
        );

        let g2: &str = "ab12cd";
        assert_parse!(
            till_line_ending.parse_peek(g2),
            str![[r#"
Ok(
    (
        "",
        "ab12cd",
    ),
)

"#]]
            .raw()
        );
    }

    #[test]
    fn hex_digit_test() {
        let i = &b"0123456789abcdefABCDEF;"[..];
        assert_parse!(
            hex_digit1.parse_peek(i),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        [
            48,
            49,
            50,
            51,
            52,
            53,
            54,
            55,
            56,
            57,
            97,
            98,
            99,
            100,
            101,
            102,
            65,
            66,
            67,
            68,
            69,
            70,
        ],
    ),
)

"#]]
            .raw()
        );

        let i = &b"g"[..];
        assert_parse!(
            hex_digit1.parse_peek(i),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                103,
            ],
        },
    ),
)

"#]]
            .raw()
        );

        let i = &b"G"[..];
        assert_parse!(
            hex_digit1.parse_peek(i),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                71,
            ],
        },
    ),
)

"#]]
            .raw()
        );

        assert!(AsChar::is_hex_digit(b'0'));
        assert!(AsChar::is_hex_digit(b'9'));
        assert!(AsChar::is_hex_digit(b'a'));
        assert!(AsChar::is_hex_digit(b'f'));
        assert!(AsChar::is_hex_digit(b'A'));
        assert!(AsChar::is_hex_digit(b'F'));
        assert!(!AsChar::is_hex_digit(b'g'));
        assert!(!AsChar::is_hex_digit(b'G'));
        assert!(!AsChar::is_hex_digit(b'/'));
        assert!(!AsChar::is_hex_digit(b':'));
        assert!(!AsChar::is_hex_digit(b'@'));
        assert!(!AsChar::is_hex_digit(b'\x60'));
    }

    #[test]
    fn oct_digit_test() {
        let i = &b"01234567;"[..];
        assert_parse!(
            oct_digit1.parse_peek(i),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        [
            48,
            49,
            50,
            51,
            52,
            53,
            54,
            55,
        ],
    ),
)

"#]]
            .raw()
        );

        let i = &b"8"[..];
        assert_parse!(
            oct_digit1.parse_peek(i),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                56,
            ],
        },
    ),
)

"#]]
            .raw()
        );

        assert!(AsChar::is_oct_digit(b'0'));
        assert!(AsChar::is_oct_digit(b'7'));
        assert!(!AsChar::is_oct_digit(b'8'));
        assert!(!AsChar::is_oct_digit(b'9'));
        assert!(!AsChar::is_oct_digit(b'a'));
        assert!(!AsChar::is_oct_digit(b'A'));
        assert!(!AsChar::is_oct_digit(b'/'));
        assert!(!AsChar::is_oct_digit(b':'));
        assert!(!AsChar::is_oct_digit(b'@'));
        assert!(!AsChar::is_oct_digit(b'\x60'));
    }

    #[test]
    fn full_line_windows() {
        #[allow(clippy::type_complexity)]
        fn take_full_line<'i>(i: &mut &'i [u8]) -> TestResult<&'i [u8], (&'i [u8], &'i [u8])> {
            (till_line_ending, line_ending).parse_next(i)
        }
        let input = b"abc\r\n";
        let output = take_full_line.parse_peek(input);
        assert_parse!(
            output,
            str![[r#"
Ok(
    (
        [],
        (
            [
                97,
                98,
                99,
            ],
            [
                13,
                10,
            ],
        ),
    ),
)

"#]]
            .raw()
        );
    }

    #[test]
    fn full_line_unix() {
        #[allow(clippy::type_complexity)]
        fn take_full_line<'i>(i: &mut &'i [u8]) -> TestResult<&'i [u8], (&'i [u8], &'i [u8])> {
            (till_line_ending, line_ending).parse_next(i)
        }
        let input = b"abc\n";
        let output = take_full_line.parse_peek(input);
        assert_parse!(
            output,
            str![[r#"
Ok(
    (
        [],
        (
            [
                97,
                98,
                99,
            ],
            [
                10,
            ],
        ),
    ),
)

"#]]
            .raw()
        );
    }

    #[test]
    fn check_windows_lineending() {
        let input = b"\r\n";
        let output = line_ending.parse_peek(&input[..]);
        assert_parse!(
            output,
            str![[r#"
Ok(
    (
        [],
        [
            13,
            10,
        ],
    ),
)

"#]]
            .raw()
        );
    }

    #[test]
    fn check_unix_lineending() {
        let input = b"\n";
        let output = line_ending.parse_peek(&input[..]);
        assert_parse!(
            output,
            str![[r#"
Ok(
    (
        [],
        [
            10,
        ],
    ),
)

"#]]
            .raw()
        );
    }

    #[test]
    fn cr_lf() {
        assert_parse!(
            crlf.parse_peek(&b"\r\na"[..]),
            str![[r#"
Ok(
    (
        [
            97,
        ],
        [
            13,
            10,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            crlf.parse_peek(&b"\r"[..]),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                13,
            ],
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            crlf.parse_peek(&b"\ra"[..]),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                13,
                97,
            ],
        },
    ),
)

"#]]
            .raw()
        );

        assert_parse!(
            crlf.parse_peek("\r\na"),
            str![[r#"
Ok(
    (
        "a",
        "\r\n",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            crlf.parse_peek("\r"),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: "\r",
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            crlf.parse_peek("\ra"),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: "\ra",
        },
    ),
)

"#]]
            .raw()
        );
    }

    #[test]
    fn end_of_line() {
        assert_parse!(
            line_ending.parse_peek(&b"\na"[..]),
            str![[r#"
Ok(
    (
        [
            97,
        ],
        [
            10,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            line_ending.parse_peek(&b"\r\na"[..]),
            str![[r#"
Ok(
    (
        [
            97,
        ],
        [
            13,
            10,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            line_ending.parse_peek(&b"\r"[..]),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                13,
            ],
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            line_ending.parse_peek(&b"\ra"[..]),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                13,
                97,
            ],
        },
    ),
)

"#]]
            .raw()
        );

        assert_parse!(
            line_ending.parse_peek("\na"),
            str![[r#"
Ok(
    (
        "a",
        "\n",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            line_ending.parse_peek("\r\na"),
            str![[r#"
Ok(
    (
        "a",
        "\r\n",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            line_ending.parse_peek("\r"),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: "\r",
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            line_ending.parse_peek("\ra"),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: "\ra",
        },
    ),
)

"#]]
            .raw()
        );
    }

    #[test]
    fn dec_uint_tests() {
        fn dec_u32<'i>(input: &mut &'i [u8]) -> TestResult<&'i [u8], u32> {
            dec_uint.parse_next(input)
        }

        assert_parse!(
            dec_u32.parse_peek(&b";"[..]),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                59,
            ],
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            dec_u32.parse_peek(&b"0;"[..]),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        0,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            dec_u32.parse_peek(&b"1;"[..]),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        1,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            dec_u32.parse_peek(&b"32;"[..]),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        32,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            dec_u32.parse_peek(&b"1000000000000000000000;"[..]), // overflow
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                49,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                59,
            ],
        },
    ),
)

"#]]
            .raw()
        );
    }

    #[test]
    fn dec_int_tests() {
        fn dec_i32<'i>(input: &mut &'i [u8]) -> TestResult<&'i [u8], i32> {
            dec_int.parse_next(input)
        }

        assert_parse!(
            dec_i32.parse_peek(&b";"[..]),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                59,
            ],
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            dec_i32.parse_peek(&b"0;"[..]),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        0,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            dec_i32.parse_peek(&b"1;"[..]),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        1,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            dec_i32.parse_peek(&b"32;"[..]),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        32,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            dec_i32.parse_peek(&b"-0;"[..]),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                45,
                48,
                59,
            ],
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            dec_i32.parse_peek(&b"-1;"[..]),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        -1,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            dec_i32.parse_peek(&b"-32;"[..]),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        -32,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            dec_i32.parse_peek(&b"1000000000000000000000;"[..]), // overflow
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                49,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                48,
                59,
            ],
        },
    ),
)

"#]]
            .raw()
        );
    }

    #[test]
    fn hex_uint_tests() {
        fn hex_u32<'i>(input: &mut &'i [u8]) -> TestResult<&'i [u8], u32> {
            hex_uint.parse_next(input)
        }

        assert_parse!(
            hex_u32.parse_peek(&b";"[..]),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                59,
            ],
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_u32.parse_peek(&b"ff;"[..]),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        255,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_u32.parse_peek(&b"1be2;"[..]),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        7138,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_u32.parse_peek(&b"c5a31be2;"[..]),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        3315801058,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_u32.parse_peek(&b"C5A31be2;"[..]),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        3315801058,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_u32.parse_peek(&b"00c5a31be2;"[..]), // overflow
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                48,
                48,
                99,
                53,
                97,
                51,
                49,
                98,
                101,
                50,
                59,
            ],
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_u32.parse_peek(&b"c5a31be201;"[..]), // overflow
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                99,
                53,
                97,
                51,
                49,
                98,
                101,
                50,
                48,
                49,
                59,
            ],
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_u32.parse_peek(&b"ffffffff;"[..]),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        4294967295,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_u32.parse_peek(&b"ffffffffffffffff;"[..]), // overflow
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                102,
                102,
                102,
                102,
                102,
                102,
                102,
                102,
                102,
                102,
                102,
                102,
                102,
                102,
                102,
                102,
                59,
            ],
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_u32.parse_peek(&b"ffffffffffffffff"[..]), // overflow
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                102,
                102,
                102,
                102,
                102,
                102,
                102,
                102,
                102,
                102,
                102,
                102,
                102,
                102,
                102,
                102,
            ],
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_u32.parse_peek(&b"0x1be2;"[..]),
            str![[r#"
Ok(
    (
        [
            120,
            49,
            98,
            101,
            50,
            59,
        ],
        0,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_u32.parse_peek(&b"12af"[..]),
            str![[r#"
Ok(
    (
        [],
        4783,
    ),
)

"#]]
            .raw()
        );
    }

    #[test]
    #[cfg(feature = "std")]
    fn float_test() {
        let test_cases = [
            "+3.14",
            "3.14",
            "-3.14",
            "0",
            "0.0",
            "1.",
            ".789",
            "-.5",
            "1e7",
            "-1E-7",
            ".3e-2",
            "1.e4",
            "1.2e4",
            "12.34",
            "-1.234E-12",
            "-1.234e-12",
            "0.00000000000000000087",
            "inf",
            "Inf",
            "infinity",
            "Infinity",
            "-inf",
            "-Inf",
            "-infinity",
            "-Infinity",
            "+inf",
            "+Inf",
            "+infinity",
            "+Infinity",
        ];

        for test in test_cases {
            let expected32 = str::parse::<f32>(test).unwrap();
            let expected64 = str::parse::<f64>(test).unwrap();

            println!("now parsing: {test} -> {expected32}");

            assert_eq!(
                float::<_, _, InputError<_>>.parse_peek(test.as_bytes()),
                Ok((&b""[..], expected32))
            );
            assert_eq!(
                float::<_, _, InputError<_>>.parse_peek(test),
                Ok(("", expected32))
            );

            assert_eq!(
                float::<_, _, InputError<_>>.parse_peek(test.as_bytes()),
                Ok((&b""[..], expected64))
            );
            assert_eq!(
                float::<_, _, InputError<_>>.parse_peek(test),
                Ok(("", expected64))
            );
        }

        let remaining_exponent = "-1.234E-";
        assert_parse!(
            float::<_, f64, _>.parse_peek(remaining_exponent),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: "",
        },
    ),
)

"#]]
            .raw()
        );

        let nan_test_cases = ["nan", "NaN", "NAN"];

        for test in nan_test_cases {
            println!("now parsing: {test}");

            let (remaining, parsed) = float::<_, f32, ()>.parse_peek(test.as_bytes()).unwrap();
            assert!(parsed.is_nan());
            assert!(remaining.is_empty());

            let (remaining, parsed) = float::<_, f32, ()>.parse_peek(test).unwrap();
            assert!(parsed.is_nan());
            assert!(remaining.is_empty());

            let (remaining, parsed) = float::<_, f64, ()>.parse_peek(test.as_bytes()).unwrap();
            assert!(parsed.is_nan());
            assert!(remaining.is_empty());

            let (remaining, parsed) = float::<_, f64, ()>.parse_peek(test).unwrap();
            assert!(parsed.is_nan());
            assert!(remaining.is_empty());
        }
    }

    proptest! {
      #[test]
      #[cfg(feature = "std")]
      #[cfg_attr(miri, ignore)]  // See https://github.com/AltSysrq/proptest/issues/253
      fn floats(s in "\\PC*") {
          println!("testing {s}");
          let res1 = parse_f64.parse_peek(&s);
          let res2 = float::<_, f64, ErrMode<()>>.parse_peek(s.as_str());
          assert_eq!(res1, res2);
      }
    }

    #[cfg(feature = "std")]
    fn parse_f64(i: &mut &str) -> ModalResult<f64, ()> {
        match take_float_or_exceptions.parse_next(i) {
            Err(e) => Err(e),
            Ok(s) => {
                if s.is_empty() {
                    return Err(ErrMode::Backtrack(()));
                }
                match s.parse_slice() {
                    Some(n) => Ok(n),
                    None => Err(ErrMode::Backtrack(())),
                }
            }
        }
    }

    // issue #1336 "take_escaped hangs if normal parser accepts empty"
    #[test]
    #[cfg_attr(debug_assertions, should_panic)]
    fn complete_take_escaped_hang_1() {
        // issue #1336 "take_escaped hangs if normal parser accepts empty"
        fn escaped_string<'i>(input: &mut &'i str) -> TestResult<&'i str, &'i str> {
            use crate::ascii::alpha0;
            use crate::token::one_of;
            take_escaped(alpha0, '\\', one_of(['n'])).parse_next(input)
        }

        let input = "7";
        assert_parse!(
            escaped_string.parse_peek(input),
            str![[r#"
Err(
    Cut(
        InputError {
            input: "7",
        },
    ),
)

"#]]
        );
    }

    // issue #1336 "take_escaped hangs if normal parser accepts empty"
    #[test]
    #[cfg_attr(debug_assertions, should_panic)]
    fn complete_take_escaped_hang_2() {
        // issue #1336 "take_escaped hangs if normal parser accepts empty"
        fn escaped_string<'i>(input: &mut &'i str) -> TestResult<&'i str, &'i str> {
            use crate::ascii::alpha0;
            use crate::token::one_of;
            take_escaped(alpha0, '\\', one_of(['n'])).parse_next(input)
        }

        let input = "a7";
        assert_parse!(
            escaped_string.parse_peek(input),
            str![[r#"
Err(
    Cut(
        InputError {
            input: "7",
        },
    ),
)

"#]]
        );
    }

    #[test]
    #[cfg_attr(debug_assertions, should_panic)]
    fn complete_take_escaped_hang_1118() {
        // issue ##1118 take_escaped does not work with empty string
        fn unquote<'i>(input: &mut &'i str) -> TestResult<&'i str, &'i str> {
            use crate::combinator::delimited;
            use crate::combinator::opt;
            use crate::token::one_of;

            delimited(
                '"',
                take_escaped(
                    opt(none_of(['\\', '"'])),
                    '\\',
                    one_of(['\\', '"', 'r', 'n', 't']),
                ),
                '"',
            )
            .parse_next(input)
        }

        let input = r#""""#;
        assert_parse!(
            unquote.parse_peek(input),
            str![[r#"
Err(
    Cut(
        InputError {
            input: "/"",
        },
    ),
)

"#]]
        );
    }

    #[cfg(feature = "alloc")]
    #[allow(unused_variables)]
    #[test]
    fn complete_escaping() {
        use crate::ascii::{alpha1 as alpha, digit1 as digit};
        use crate::token::one_of;

        fn esc<'i>(i: &mut &'i [u8]) -> TestResult<&'i [u8], &'i [u8]> {
            take_escaped(alpha, '\\', one_of(['\"', 'n', '\\'])).parse_next(i)
        }
        assert_parse!(
            esc.parse_peek(&b"abcd;"[..]),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        [
            97,
            98,
            99,
            100,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek(&b"ab\\\"cd;"[..]),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        [
            97,
            98,
            92,
            34,
            99,
            100,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek(&b"\\\"abcd;"[..]),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        [
            92,
            34,
            97,
            98,
            99,
            100,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek(&b"\\n;"[..]),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        [
            92,
            110,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek(&b"ab\\\"12"[..]),
            str![[r#"
Ok(
    (
        [
            49,
            50,
        ],
        [
            97,
            98,
            92,
            34,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek(&b"AB\\"[..]),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [],
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek(&b"AB\\A"[..]),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                65,
            ],
        },
    ),
)

"#]]
            .raw()
        );

        fn esc2<'i>(i: &mut &'i [u8]) -> TestResult<&'i [u8], &'i [u8]> {
            take_escaped(digit, '\\', one_of(['\"', 'n', '\\'])).parse_next(i)
        }
        assert_parse!(
            esc2.parse_peek(&b"12\\nnn34"[..]),
            str![[r#"
Ok(
    (
        [
            110,
            110,
            51,
            52,
        ],
        [
            49,
            50,
            92,
            110,
        ],
    ),
)

"#]]
            .raw()
        );
    }

    #[cfg(feature = "alloc")]
    #[test]
    fn complete_escaping_str() {
        use crate::ascii::{alpha1 as alpha, digit1 as digit};
        use crate::token::one_of;

        fn esc<'i>(i: &mut &'i str) -> TestResult<&'i str, &'i str> {
            take_escaped(alpha, '\\', one_of(['\"', 'n', '\\'])).parse_next(i)
        }
        assert_parse!(
            esc.parse_peek("abcd;"),
            str![[r#"
Ok(
    (
        ";",
        "abcd",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek("ab\\\"cd;"),
            str![[r#"
Ok(
    (
        ";",
        "ab\\\"cd",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek("\\\"abcd;"),
            str![[r#"
Ok(
    (
        ";",
        "\\\"abcd",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek("\\n;"),
            str![[r#"
Ok(
    (
        ";",
        "\\n",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek("ab\\\"12"),
            str![[r#"
Ok(
    (
        "12",
        "ab\\\"",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek("AB\\"),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: "",
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek("AB\\A"),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: "A",
        },
    ),
)

"#]]
            .raw()
        );

        fn esc2<'i>(i: &mut &'i str) -> TestResult<&'i str, &'i str> {
            take_escaped(digit, '\\', one_of(['\"', 'n', '\\'])).parse_next(i)
        }
        assert_parse!(
            esc2.parse_peek("12\\nnn34"),
            str![[r#"
Ok(
    (
        "nn34",
        "12\\n",
    ),
)

"#]]
            .raw()
        );

        fn esc3<'i>(i: &mut &'i str) -> TestResult<&'i str, &'i str> {
            take_escaped(alpha, '\u{241b}', one_of(['\"', 'n'])).parse_next(i)
        }
        assert_parse!(
            esc3.parse_peek("ab␛ncd;"),
            str![[r#"
Ok(
    (
        ";",
        "ab␛ncd",
    ),
)

"#]]
            .raw()
        );
    }

    #[test]
    fn test_take_escaped_error() {
        fn esc<'i>(i: &mut &'i str) -> TestResult<&'i str, &'i str> {
            use crate::ascii::digit1;
            take_escaped(digit1, '\\', one_of(['\"', 'n', '\\'])).parse_next(i)
        }

        assert_parse!(
            esc.parse_peek("abcd"),
            str![[r#"
Ok(
    (
        "abcd",
        "",
    ),
)

"#]]
            .raw()
        );
    }

    #[cfg(feature = "alloc")]
    #[test]
    fn complete_escape_transform() {
        use crate::ascii::alpha1 as alpha;

        #[cfg(feature = "alloc")]
        fn to_s(i: Vec<u8>) -> String {
            String::from_utf8_lossy(&i).into_owned()
        }

        fn esc<'i>(i: &mut &'i [u8]) -> TestResult<&'i [u8], String> {
            escaped(alpha, '\\', alt((b'\\', b'"', "n".value(b'\n'))))
                .map(to_s)
                .parse_next(i)
        }

        assert_parse!(
            esc.parse_peek(&b"abcd;"[..]),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        "abcd",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek(&b"ab\\\"cd;"[..]),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        "ab\"cd",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek(&b"\\\"abcd;"[..]),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        "\"abcd",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek(&b"\\n;"[..]),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        "\n",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek(&b"ab\\\"12"[..]),
            str![[r#"
Ok(
    (
        [
            49,
            50,
        ],
        "ab\"",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek(&b"AB\\"[..]),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [],
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek(&b"AB\\A"[..]),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                65,
            ],
        },
    ),
)

"#]]
            .raw()
        );

        fn esc2<'i>(i: &mut &'i [u8]) -> TestResult<&'i [u8], String> {
            escaped(
                alpha,
                '&',
                alt((
                    "egrave;".value("è".as_bytes()),
                    "agrave;".value("à".as_bytes()),
                )),
            )
            .map(to_s)
            .parse_next(i)
        }
        assert_parse!(
            esc2.parse_peek(&b"ab&egrave;DEF;"[..]),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        "abèDEF",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc2.parse_peek(&b"ab&egrave;D&agrave;EF;"[..]),
            str![[r#"
Ok(
    (
        [
            59,
        ],
        "abèDàEF",
    ),
)

"#]]
            .raw()
        );
    }

    #[cfg(feature = "std")]
    #[test]
    fn complete_escape_transform_str() {
        use crate::ascii::alpha1 as alpha;

        fn esc<'i>(i: &mut &'i str) -> TestResult<&'i str, String> {
            escaped(
                alpha,
                '\\',
                alt((
                    '\\',
                    '"',
                    "n".value('\n'),
                    ("x", hex_uint).map(|(_, hex)| char::from_u32(hex).unwrap()),
                )),
            )
            .parse_next(i)
        }

        assert_parse!(
            esc.parse_peek("abcd;"),
            str![[r#"
Ok(
    (
        ";",
        "abcd",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek("ab\\\"cd;"),
            str![[r#"
Ok(
    (
        ";",
        "ab\"cd",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek("\\\"abcd;"),
            str![[r#"
Ok(
    (
        ";",
        "\"abcd",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek("\\n;"),
            str![[r#"
Ok(
    (
        ";",
        "\n",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek("ab\\\"12"),
            str![[r#"
Ok(
    (
        "12",
        "ab\"",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek("ab\\x20"),
            str![[r#"
Ok(
    (
        "",
        "ab ",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek("AB\\"),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: "",
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek("AB\\A"),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: "A",
        },
    ),
)

"#]]
            .raw()
        );

        fn esc2<'i>(i: &mut &'i str) -> TestResult<&'i str, String> {
            escaped(
                alpha,
                '&',
                alt(("egrave;".value("è"), "agrave;".value("à"))),
            )
            .parse_next(i)
        }
        assert_parse!(
            esc2.parse_peek("ab&egrave;DEF;"),
            str![[r#"
Ok(
    (
        ";",
        "abèDEF",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc2.parse_peek("ab&egrave;D&agrave;EF;"),
            str![[r#"
Ok(
    (
        ";",
        "abèDàEF",
    ),
)

"#]]
            .raw()
        );

        fn esc3<'i>(i: &mut &'i str) -> TestResult<&'i str, String> {
            escaped(alpha, '␛', alt(("0".value("\0"), "n".value("\n")))).parse_next(i)
        }
        assert_parse!(
            esc3.parse_peek("a␛0bc␛n"),
            str![[r#"
Ok(
    (
        "",
        "a\0bc\n",
    ),
)

"#]]
            .raw()
        );
    }

    #[cfg(feature = "std")]
    #[test]
    fn complete_escape_transform_cow() {
        use crate::ascii::alpha1 as alpha;

        fn esc<'i>(i: &mut &'i str) -> TestResult<&'i str, alloc::borrow::Cow<'i, str>> {
            escaped(
                alpha,
                '\\',
                alt((
                    '\\',
                    '"',
                    "n".value('\n'),
                    ("x", hex_uint).map(|(_, hex)| char::from_u32(hex).unwrap()),
                )),
            )
            .parse_next(i)
        }

        assert_parse!(
            esc.parse_peek("abcd;"),
            str![[r#"
Ok(
    (
        ";",
        "abcd",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek("ab\\\"cd;"),
            str![[r#"
Ok(
    (
        ";",
        "ab\"cd",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek("\\\"abcd;"),
            str![[r#"
Ok(
    (
        ";",
        "\"abcd",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek("\\n;"),
            str![[r#"
Ok(
    (
        ";",
        "\n",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek("ab\\\"12"),
            str![[r#"
Ok(
    (
        "12",
        "ab\"",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek("ab\\x20"),
            str![[r#"
Ok(
    (
        "",
        "ab ",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek("AB\\"),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: "",
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc.parse_peek("AB\\A"),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: "A",
        },
    ),
)

"#]]
            .raw()
        );

        fn esc2<'i>(i: &mut &'i str) -> TestResult<&'i str, alloc::borrow::Cow<'i, str>> {
            escaped(
                alpha,
                '&',
                alt(("egrave;".value("è"), "agrave;".value("à"))),
            )
            .parse_next(i)
        }
        assert_parse!(
            esc2.parse_peek("ab&egrave;DEF;"),
            str![[r#"
Ok(
    (
        ";",
        "abèDEF",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            esc2.parse_peek("ab&egrave;D&agrave;EF;"),
            str![[r#"
Ok(
    (
        ";",
        "abèDàEF",
    ),
)

"#]]
            .raw()
        );

        fn esc3<'i>(i: &mut &'i str) -> TestResult<&'i str, String> {
            escaped(alpha, '␛', alt(("0".value("\0"), "n".value("\n")))).parse_next(i)
        }
        assert_parse!(
            esc3.parse_peek("a␛0bc␛n"),
            str![[r#"
Ok(
    (
        "",
        "a\0bc\n",
    ),
)

"#]]
            .raw()
        );
    }

    #[test]
    #[cfg(feature = "alloc")]
    fn test_escaped_error() {
        fn esc_trans<'i>(i: &mut &'i str) -> TestResult<&'i str, String> {
            use crate::ascii::digit1;
            escaped(digit1, '\\', "n").parse_next(i)
        }

        assert_parse!(
            esc_trans.parse_peek("abcd"),
            str![[r#"
Ok(
    (
        "abcd",
        "",
    ),
)

"#]]
            .raw()
        );
    }

    #[test]
    #[cfg(feature = "alloc")]
    fn try_fesc() {
        const FEND: u8 = 0xC0;
        const FESC: u8 = 0xDB;
        const TFEND: u8 = 0xDC;
        const TFESC: u8 = 0xDD;

        fn unescape<'i>(input: &mut &'i [u8]) -> TestResult<&'i [u8], Vec<u8>> {
            escaped(
                take_till(1.., [FESC].as_slice()),
                FESC,
                alt((
                    (&[TFEND][..]).value(&[FEND][..]),
                    (&[TFESC][..]).value(&[FESC][..]),
                )),
            )
            .parse_next(input)
        }

        // fesc
        let input = &[0x61, 0x62, FESC, TFEND, 0x63, 0x64, 0x65][..];
        assert_parse!(
            unescape.parse_peek(input),
            str![[r#"
Ok(
    (
        [],
        [
            97,
            98,
            192,
            99,
            100,
            101,
        ],
    ),
)

"#]]
        );

        // fesczerozero
        let input = &[0x61, FESC, 0x00, TFEND, 0x63, 0x64][..];
        assert_parse!(
            unescape.parse_peek(input),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: [
                0,
                220,
                99,
                100,
            ],
        },
    ),
)

"#]]
        );

        // noesc
        let input = &[0x61, 0x62, 0x63][..];
        assert_parse!(
            unescape.parse_peek(input),
            str![[r#"
Ok(
    (
        [],
        [
            97,
            98,
            99,
        ],
    ),
)

"#]]
        );
    }
}

mod partial {
    use super::*;

    use crate::error::InputError;
    use crate::prelude::*;
    use crate::Partial;

    #[test]
    fn character() {
        let a: &[u8] = b"abcd";
        let b: &[u8] = b"1234";
        let c: &[u8] = b"a123";
        let d: &[u8] = "azé12".as_bytes();
        let e: &[u8] = b" ";
        let f: &[u8] = b" ;";
        //assert_parse!(alpha1::<_, Error<_>>(a), Err(ErrMode::Incomplete(Needed::new(1))));
        assert_parse!(
            alpha1.parse_peek(Partial::new(a)),
            str![[r#"
Err(
    Incomplete(
        Size(
            1,
        ),
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            alpha1.parse_peek(Partial::new(b)),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: [
                    49,
                    50,
                    51,
                    52,
                ],
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            alpha1.parse_peek(Partial::new(c)),
            str![[r#"
Ok(
    (
        Partial {
            input: [
                49,
                50,
                51,
            ],
            partial: true,
        },
        [
            97,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            alpha1.parse_peek(Partial::new(d)),
            str![[r#"
Ok(
    (
        Partial {
            input: [
                195,
                169,
                49,
                50,
            ],
            partial: true,
        },
        [
            97,
            122,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            digit1.parse_peek(Partial::new(a)),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: [
                    97,
                    98,
                    99,
                    100,
                ],
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            digit1.parse_peek(Partial::new(b)),
            str![[r#"
Err(
    Incomplete(
        Size(
            1,
        ),
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            digit1.parse_peek(Partial::new(c)),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: [
                    97,
                    49,
                    50,
                    51,
                ],
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            digit1.parse_peek(Partial::new(d)),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: [
                    97,
                    122,
                    195,
                    169,
                    49,
                    50,
                ],
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_digit1.parse_peek(Partial::new(a)),
            str![[r#"
Err(
    Incomplete(
        Size(
            1,
        ),
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_digit1.parse_peek(Partial::new(b)),
            str![[r#"
Err(
    Incomplete(
        Size(
            1,
        ),
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_digit1.parse_peek(Partial::new(c)),
            str![[r#"
Err(
    Incomplete(
        Size(
            1,
        ),
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_digit1.parse_peek(Partial::new(d)),
            str![[r#"
Ok(
    (
        Partial {
            input: [
                122,
                195,
                169,
                49,
                50,
            ],
            partial: true,
        },
        [
            97,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_digit1.parse_peek(Partial::new(e)),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: [
                    32,
                ],
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            oct_digit1.parse_peek(Partial::new(a)),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: [
                    97,
                    98,
                    99,
                    100,
                ],
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            oct_digit1.parse_peek(Partial::new(b)),
            str![[r#"
Err(
    Incomplete(
        Size(
            1,
        ),
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            oct_digit1.parse_peek(Partial::new(c)),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: [
                    97,
                    49,
                    50,
                    51,
                ],
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            oct_digit1.parse_peek(Partial::new(d)),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: [
                    97,
                    122,
                    195,
                    169,
                    49,
                    50,
                ],
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            alphanumeric1.parse_peek(Partial::new(a)),
            str![[r#"
Err(
    Incomplete(
        Size(
            1,
        ),
    ),
)

"#]]
            .raw()
        );
        //assert_parse!(fix_error!(b,(), alphanumeric1), str![]);
        assert_parse!(
            alphanumeric1.parse_peek(Partial::new(c)),
            str![[r#"
Err(
    Incomplete(
        Size(
            1,
        ),
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            alphanumeric1.parse_peek(Partial::new(d)),
            str![[r#"
Ok(
    (
        Partial {
            input: [
                195,
                169,
                49,
                50,
            ],
            partial: true,
        },
        [
            97,
            122,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            space1.parse_peek(Partial::new(e)),
            str![[r#"
Err(
    Incomplete(
        Size(
            1,
        ),
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            space1.parse_peek(Partial::new(f)),
            str![[r#"
Ok(
    (
        Partial {
            input: [
                59,
            ],
            partial: true,
        },
        [
            32,
        ],
    ),
)

"#]]
            .raw()
        );
    }

    #[cfg(feature = "alloc")]
    #[test]
    fn character_s() {
        let a = "abcd";
        let b = "1234";
        let c = "a123";
        let d = "azé12";
        let e = " ";
        assert_parse!(
            alpha1.parse_peek(Partial::new(a)),
            str![[r#"
Err(
    Incomplete(
        Size(
            1,
        ),
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            alpha1.parse_peek(Partial::new(b)),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: "1234",
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            alpha1.parse_peek(Partial::new(c)),
            str![[r#"
Ok(
    (
        Partial {
            input: "123",
            partial: true,
        },
        "a",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            alpha1.parse_peek(Partial::new(d)),
            str![[r#"
Ok(
    (
        Partial {
            input: "é12",
            partial: true,
        },
        "az",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            digit1.parse_peek(Partial::new(a)),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: "abcd",
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            digit1.parse_peek(Partial::new(b)),
            str![[r#"
Err(
    Incomplete(
        Size(
            1,
        ),
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            digit1.parse_peek(Partial::new(c)),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: "a123",
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            digit1.parse_peek(Partial::new(d)),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: "azé12",
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_digit1.parse_peek(Partial::new(a)),
            str![[r#"
Err(
    Incomplete(
        Size(
            1,
        ),
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_digit1.parse_peek(Partial::new(b)),
            str![[r#"
Err(
    Incomplete(
        Size(
            1,
        ),
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_digit1.parse_peek(Partial::new(c)),
            str![[r#"
Err(
    Incomplete(
        Size(
            1,
        ),
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_digit1.parse_peek(Partial::new(d)),
            str![[r#"
Ok(
    (
        Partial {
            input: "zé12",
            partial: true,
        },
        "a",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_digit1.parse_peek(Partial::new(e)),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: " ",
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            oct_digit1.parse_peek(Partial::new(a)),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: "abcd",
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            oct_digit1.parse_peek(Partial::new(b)),
            str![[r#"
Err(
    Incomplete(
        Size(
            1,
        ),
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            oct_digit1.parse_peek(Partial::new(c)),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: "a123",
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            oct_digit1.parse_peek(Partial::new(d)),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: "azé12",
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            alphanumeric1.parse_peek(Partial::new(a)),
            str![[r#"
Err(
    Incomplete(
        Size(
            1,
        ),
    ),
)

"#]]
            .raw()
        );
        //assert_parse!(fix_error!(b,(), alphanumeric1), str![]);
        assert_parse!(
            alphanumeric1.parse_peek(Partial::new(c)),
            str![[r#"
Err(
    Incomplete(
        Size(
            1,
        ),
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            alphanumeric1.parse_peek(Partial::new(d)),
            str![[r#"
Ok(
    (
        Partial {
            input: "é12",
            partial: true,
        },
        "az",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            space1.parse_peek(Partial::new(e)),
            str![[r#"
Err(
    Incomplete(
        Size(
            1,
        ),
    ),
)

"#]]
            .raw()
        );
    }

    use crate::stream::Offset;
    #[test]
    fn offset() {
        let a = &b"abcd;"[..];
        let b = &b"1234;"[..];
        let c = &b"a123;"[..];
        let d = &b" \t;"[..];
        let e = &b" \t\r\n;"[..];
        let f = &b"123abcDEF;"[..];

        match alpha1::<_, InputError<_>>.parse_peek(Partial::new(a)) {
            Ok((i, _)) => {
                let i = i.into_inner();
                assert_eq!(i.offset_from(&a) + i.len(), a.len());
            }
            _ => panic!("wrong return type in offset test for alpha"),
        }
        match digit1::<_, InputError<_>>.parse_peek(Partial::new(b)) {
            Ok((i, _)) => {
                let i = i.into_inner();
                assert_eq!(i.offset_from(&b) + i.len(), b.len());
            }
            _ => panic!("wrong return type in offset test for digit"),
        }
        match alphanumeric1::<_, InputError<_>>.parse_peek(Partial::new(c)) {
            Ok((i, _)) => {
                let i = i.into_inner();
                assert_eq!(i.offset_from(&c) + i.len(), c.len());
            }
            _ => panic!("wrong return type in offset test for alphanumeric"),
        }
        match space1::<_, InputError<_>>.parse_peek(Partial::new(d)) {
            Ok((i, _)) => {
                let i = i.into_inner();
                assert_eq!(i.offset_from(&d) + i.len(), d.len());
            }
            _ => panic!("wrong return type in offset test for space"),
        }
        match multispace1::<_, InputError<_>>.parse_peek(Partial::new(e)) {
            Ok((i, _)) => {
                let i = i.into_inner();
                assert_eq!(i.offset_from(&e) + i.len(), e.len());
            }
            _ => panic!("wrong return type in offset test for multispace"),
        }
        match hex_digit1::<_, InputError<_>>.parse_peek(Partial::new(f)) {
            Ok((i, _)) => {
                let i = i.into_inner();
                assert_eq!(i.offset_from(&f) + i.len(), f.len());
            }
            _ => panic!("wrong return type in offset test for hex_digit"),
        }
        match oct_digit1::<_, InputError<_>>.parse_peek(Partial::new(f)) {
            Ok((i, _)) => {
                let i = i.into_inner();
                assert_eq!(i.offset_from(&f) + i.len(), f.len());
            }
            _ => panic!("wrong return type in offset test for oct_digit"),
        }
    }

    #[test]
    fn is_till_line_ending_bytes() {
        let a: &[u8] = b"ab12cd\nefgh";
        assert_parse!(
            till_line_ending.parse_peek(Partial::new(a)),
            str![[r#"
Ok(
    (
        Partial {
            input: [
                10,
                101,
                102,
                103,
                104,
            ],
            partial: true,
        },
        [
            97,
            98,
            49,
            50,
            99,
            100,
        ],
    ),
)

"#]]
            .raw()
        );

        let b: &[u8] = b"ab12cd\nefgh\nijkl";
        assert_parse!(
            till_line_ending.parse_peek(Partial::new(b)),
            str![[r#"
Ok(
    (
        Partial {
            input: [
                10,
                101,
                102,
                103,
                104,
                10,
                105,
                106,
                107,
                108,
            ],
            partial: true,
        },
        [
            97,
            98,
            49,
            50,
            99,
            100,
        ],
    ),
)

"#]]
            .raw()
        );

        let c: &[u8] = b"ab12cd\r\nefgh\nijkl";
        assert_parse!(
            till_line_ending.parse_peek(Partial::new(c)),
            str![[r#"
Ok(
    (
        Partial {
            input: [
                13,
                10,
                101,
                102,
                103,
                104,
                10,
                105,
                106,
                107,
                108,
            ],
            partial: true,
        },
        [
            97,
            98,
            49,
            50,
            99,
            100,
        ],
    ),
)

"#]]
            .raw()
        );

        let d: &[u8] = b"ab12cd";
        assert_parse!(
            till_line_ending.parse_peek(Partial::new(d)),
            str![[r#"
Err(
    Incomplete(
        Unknown,
    ),
)

"#]]
            .raw()
        );
    }

    #[test]
    fn is_till_line_ending_str() {
        let f = "βèƒôřè\rÂßÇáƒƭèř";
        assert_parse!(
            till_line_ending.parse_peek(Partial::new(f)),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: "\rÂßÇáƒƭèř",
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );

        let g2: &str = "ab12cd";
        assert_parse!(
            till_line_ending.parse_peek(Partial::new(g2)),
            str![[r#"
Err(
    Incomplete(
        Unknown,
    ),
)

"#]]
            .raw()
        );
    }

    #[test]
    fn hex_digit_test() {
        let i = &b"0123456789abcdefABCDEF;"[..];
        assert_parse!(
            hex_digit1.parse_peek(Partial::new(i)),
            str![[r#"
Ok(
    (
        Partial {
            input: [
                59,
            ],
            partial: true,
        },
        [
            48,
            49,
            50,
            51,
            52,
            53,
            54,
            55,
            56,
            57,
            97,
            98,
            99,
            100,
            101,
            102,
            65,
            66,
            67,
            68,
            69,
            70,
        ],
    ),
)

"#]]
            .raw()
        );

        let i = &b"g"[..];
        assert_parse!(
            hex_digit1.parse_peek(Partial::new(i)),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: [
                    103,
                ],
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );

        let i = &b"G"[..];
        assert_parse!(
            hex_digit1.parse_peek(Partial::new(i)),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: [
                    71,
                ],
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );

        assert!(AsChar::is_hex_digit(b'0'));
        assert!(AsChar::is_hex_digit(b'9'));
        assert!(AsChar::is_hex_digit(b'a'));
        assert!(AsChar::is_hex_digit(b'f'));
        assert!(AsChar::is_hex_digit(b'A'));
        assert!(AsChar::is_hex_digit(b'F'));
        assert!(!AsChar::is_hex_digit(b'g'));
        assert!(!AsChar::is_hex_digit(b'G'));
        assert!(!AsChar::is_hex_digit(b'/'));
        assert!(!AsChar::is_hex_digit(b':'));
        assert!(!AsChar::is_hex_digit(b'@'));
        assert!(!AsChar::is_hex_digit(b'\x60'));
    }

    #[test]
    fn oct_digit_test() {
        let i = &b"01234567;"[..];
        assert_parse!(
            oct_digit1.parse_peek(Partial::new(i)),
            str![[r#"
Ok(
    (
        Partial {
            input: [
                59,
            ],
            partial: true,
        },
        [
            48,
            49,
            50,
            51,
            52,
            53,
            54,
            55,
        ],
    ),
)

"#]]
            .raw()
        );

        let i = &b"8"[..];
        assert_parse!(
            oct_digit1.parse_peek(Partial::new(i)),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: [
                    56,
                ],
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );

        assert!(AsChar::is_oct_digit(b'0'));
        assert!(AsChar::is_oct_digit(b'7'));
        assert!(!AsChar::is_oct_digit(b'8'));
        assert!(!AsChar::is_oct_digit(b'9'));
        assert!(!AsChar::is_oct_digit(b'a'));
        assert!(!AsChar::is_oct_digit(b'A'));
        assert!(!AsChar::is_oct_digit(b'/'));
        assert!(!AsChar::is_oct_digit(b':'));
        assert!(!AsChar::is_oct_digit(b'@'));
        assert!(!AsChar::is_oct_digit(b'\x60'));
    }

    #[test]
    fn full_line_windows() {
        #[allow(clippy::type_complexity)]
        fn take_full_line<'i>(
            i: &mut Partial<&'i [u8]>,
        ) -> TestResult<Partial<&'i [u8]>, (&'i [u8], &'i [u8])> {
            (till_line_ending, line_ending).parse_next(i)
        }
        let input = b"abc\r\n";
        let output = take_full_line.parse_peek(Partial::new(input));
        assert_parse!(
            output,
            str![[r#"
Ok(
    (
        Partial {
            input: [],
            partial: true,
        },
        (
            [
                97,
                98,
                99,
            ],
            [
                13,
                10,
            ],
        ),
    ),
)

"#]]
            .raw()
        );
    }

    #[test]
    fn full_line_unix() {
        #[allow(clippy::type_complexity)]
        fn take_full_line<'i>(
            i: &mut Partial<&'i [u8]>,
        ) -> TestResult<Partial<&'i [u8]>, (&'i [u8], &'i [u8])> {
            (till_line_ending, line_ending).parse_next(i)
        }
        let input = b"abc\n";
        let output = take_full_line.parse_peek(Partial::new(input));
        assert_parse!(
            output,
            str![[r#"
Ok(
    (
        Partial {
            input: [],
            partial: true,
        },
        (
            [
                97,
                98,
                99,
            ],
            [
                10,
            ],
        ),
    ),
)

"#]]
            .raw()
        );
    }

    #[test]
    fn check_windows_lineending() {
        let input = b"\r\n";
        let output = line_ending.parse_peek(Partial::new(&input[..]));
        assert_parse!(
            output,
            str![[r#"
Ok(
    (
        Partial {
            input: [],
            partial: true,
        },
        [
            13,
            10,
        ],
    ),
)

"#]]
            .raw()
        );
    }

    #[test]
    fn check_unix_lineending() {
        let input = b"\n";
        let output = line_ending.parse_peek(Partial::new(&input[..]));
        assert_parse!(
            output,
            str![[r#"
Ok(
    (
        Partial {
            input: [],
            partial: true,
        },
        [
            10,
        ],
    ),
)

"#]]
            .raw()
        );
    }

    #[test]
    fn cr_lf() {
        assert_parse!(
            crlf.parse_peek(Partial::new(&b"\r\na"[..])),
            str![[r#"
Ok(
    (
        Partial {
            input: [
                97,
            ],
            partial: true,
        },
        [
            13,
            10,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            crlf.parse_peek(Partial::new(&b"\r"[..])),
            str![[r#"
Err(
    Incomplete(
        Unknown,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            crlf.parse_peek(Partial::new(&b"\ra"[..])),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: [
                    13,
                    97,
                ],
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );

        assert_parse!(
            crlf.parse_peek(Partial::new("\r\na")),
            str![[r#"
Ok(
    (
        Partial {
            input: "a",
            partial: true,
        },
        "\r\n",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            crlf.parse_peek(Partial::new("\r")),
            str![[r#"
Err(
    Incomplete(
        Unknown,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            crlf.parse_peek(Partial::new("\ra")),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: "\ra",
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );
    }

    #[test]
    fn end_of_line() {
        assert_parse!(
            line_ending.parse_peek(Partial::new(&b"\na"[..])),
            str![[r#"
Ok(
    (
        Partial {
            input: [
                97,
            ],
            partial: true,
        },
        [
            10,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            line_ending.parse_peek(Partial::new(&b"\r\na"[..])),
            str![[r#"
Ok(
    (
        Partial {
            input: [
                97,
            ],
            partial: true,
        },
        [
            13,
            10,
        ],
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            line_ending.parse_peek(Partial::new(&b"\r"[..])),
            str![[r#"
Err(
    Incomplete(
        Unknown,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            line_ending.parse_peek(Partial::new(&b"\ra"[..])),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: [
                    13,
                    97,
                ],
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );

        assert_parse!(
            line_ending.parse_peek(Partial::new("\na")),
            str![[r#"
Ok(
    (
        Partial {
            input: "a",
            partial: true,
        },
        "\n",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            line_ending.parse_peek(Partial::new("\r\na")),
            str![[r#"
Ok(
    (
        Partial {
            input: "a",
            partial: true,
        },
        "\r\n",
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            line_ending.parse_peek(Partial::new("\r")),
            str![[r#"
Err(
    Incomplete(
        Unknown,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            line_ending.parse_peek(Partial::new("\ra")),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: "\ra",
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );
    }

    #[test]
    fn hex_uint_tests() {
        fn hex_u32<'i>(input: &mut Partial<&'i [u8]>) -> TestResult<Partial<&'i [u8]>, u32> {
            hex_uint.parse_next(input)
        }

        assert_parse!(
            hex_u32.parse_peek(Partial::new(&b";"[..])),
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: [
                    59,
                ],
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_u32.parse_peek(Partial::new(&b"ff;"[..])),
            str![[r#"
Ok(
    (
        Partial {
            input: [
                59,
            ],
            partial: true,
        },
        255,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_u32.parse_peek(Partial::new(&b"1be2;"[..])),
            str![[r#"
Ok(
    (
        Partial {
            input: [
                59,
            ],
            partial: true,
        },
        7138,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_u32.parse_peek(Partial::new(&b"c5a31be2;"[..])),
            str![[r#"
Ok(
    (
        Partial {
            input: [
                59,
            ],
            partial: true,
        },
        3315801058,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_u32.parse_peek(Partial::new(&b"C5A31be2;"[..])),
            str![[r#"
Ok(
    (
        Partial {
            input: [
                59,
            ],
            partial: true,
        },
        3315801058,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_u32.parse_peek(Partial::new(&b"00c5a31be2;"[..])), // overflow
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: [
                    48,
                    48,
                    99,
                    53,
                    97,
                    51,
                    49,
                    98,
                    101,
                    50,
                    59,
                ],
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_u32.parse_peek(Partial::new(&b"c5a31be201;"[..])), // overflow
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: [
                    99,
                    53,
                    97,
                    51,
                    49,
                    98,
                    101,
                    50,
                    48,
                    49,
                    59,
                ],
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_u32.parse_peek(Partial::new(&b"ffffffff;"[..])),
            str![[r#"
Ok(
    (
        Partial {
            input: [
                59,
            ],
            partial: true,
        },
        4294967295,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_u32.parse_peek(Partial::new(&b"ffffffffffffffff;"[..])), // overflow
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: [
                    102,
                    102,
                    102,
                    102,
                    102,
                    102,
                    102,
                    102,
                    102,
                    102,
                    102,
                    102,
                    102,
                    102,
                    102,
                    102,
                    59,
                ],
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_u32.parse_peek(Partial::new(&b"ffffffffffffffff"[..])), // overflow
            str![[r#"
Err(
    Backtrack(
        InputError {
            input: Partial {
                input: [
                    102,
                    102,
                    102,
                    102,
                    102,
                    102,
                    102,
                    102,
                    102,
                    102,
                    102,
                    102,
                    102,
                    102,
                    102,
                    102,
                ],
                partial: true,
            },
        },
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_u32.parse_peek(Partial::new(&b"0x1be2;"[..])),
            str![[r#"
Ok(
    (
        Partial {
            input: [
                120,
                49,
                98,
                101,
                50,
                59,
            ],
            partial: true,
        },
        0,
    ),
)

"#]]
            .raw()
        );
        assert_parse!(
            hex_u32.parse_peek(Partial::new(&b"12af"[..])),
            str![[r#"
Err(
    Incomplete(
        Size(
            1,
        ),
    ),
)

"#]]
            .raw()
        );
    }
}
