use super::*; use snapbox::prelude::*; use snapbox::str; 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; #[cfg(feature = "alloc")] use crate::{lib::std::string::String, lib::std::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::(test).unwrap(); let expected64 = str::parse::(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 { 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) -> 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èDEF;"[..]), str![[r#" Ok( ( [ 59, ], "abèDEF", ), ) "#]] .raw() ); assert_parse!( esc2.parse_peek(&b"abèDà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èDEF;"), str![[r#" Ok( ( ";", "abèDEF", ), ) "#]] .raw() ); assert_parse!( esc2.parse_peek("abèDà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() ); } } 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, (&'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, (&'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, 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() ); } }