use super::*; use snapbox::prelude::*; use snapbox::str; use crate::ascii::digit1 as digit; use crate::binary::u16; use crate::binary::u8; use crate::binary::Endianness; use crate::error::ErrMode; use crate::error::ParserError; #[cfg(feature = "alloc")] use crate::lib::std::borrow::ToOwned; use crate::prelude::*; use crate::stream::Stream; use crate::token::take; use crate::ModalResult; use crate::Partial; #[cfg(feature = "alloc")] use crate::lib::std::vec::Vec; #[test] fn eof_on_slices() { let not_over: &[u8] = &b"Hello, world!"[..]; let is_over: &[u8] = &b""[..]; let res_not_over = eof.parse_peek(not_over); assert_parse!( res_not_over, str![[r#" Err( Backtrack( InputError { input: [ 72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33, ], }, ), ) "#]] .raw() ); let res_over = eof.parse_peek(is_over); assert_parse!( res_over, str![[r#" Ok( ( [], [], ), ) "#]] .raw() ); } #[test] fn eof_on_strs() { let not_over: &str = "Hello, world!"; let is_over: &str = ""; let res_not_over = eof.parse_peek(not_over); assert_parse!( res_not_over, str![[r#" Err( Backtrack( InputError { input: "Hello, world!", }, ), ) "#]] .raw() ); let res_over = eof.parse_peek(is_over); assert_parse!( res_over, str![[r#" Ok( ( "", "", ), ) "#]] .raw() ); } use crate::lib::std::convert::From; impl From for CustomError { fn from(_: u32) -> Self { CustomError } } impl ParserError for CustomError { type Inner = Self; fn from_input(_: &I) -> Self { CustomError } fn into_inner(self) -> Result { Ok(self) } } struct CustomError; #[allow(dead_code)] fn custom_error<'i>(input: &mut &'i [u8]) -> ModalResult<&'i [u8], CustomError> { //fix_error!(input, CustomError<_>, alphanumeric) crate::ascii::alphanumeric1.parse_next(input) } #[test] fn test_parser_flat_map() { let input: &[u8] = &[3, 100, 101, 102, 103, 104][..]; assert_parse!( u8.flat_map(take).parse_peek(input), str![[r#" Ok( ( [ 103, 104, ], [ 100, 101, 102, ], ), ) "#]] .raw() ); } #[allow(dead_code)] fn test_closure_compiles_195(input: &mut &[u8]) -> ModalResult<()> { u8.flat_map(|num| repeat(num as usize, u16(Endianness::Big))) .parse_next(input) } #[test] fn test_parser_verify_map() { let input: &[u8] = &[50][..]; assert_parse!( u8.verify_map(|u| if u < 20 { Some(u) } else { None }) .parse_peek(input), str![[r#" Err( Backtrack( InputError { input: [ 50, ], }, ), ) "#]] .raw() ); assert_parse!( u8.verify_map(|u| if u > 20 { Some(u) } else { None }) .parse_peek(input), str![[r#" Ok( ( [], 50, ), ) "#]] .raw() ); } #[test] fn test_parser_map_parser() { let input: &[u8] = &[100, 101, 102, 103, 104][..]; assert_parse!( take(4usize).and_then(take(2usize)).parse_peek(input), str![[r#" Ok( ( [ 104, ], [ 100, 101, ], ), ) "#]] .raw() ); } #[test] #[cfg(feature = "std")] fn test_parser_into() { use crate::token::take; assert_parse!( take(3u8) .output_into::>() .parse_peek(&b"abcdefg"[..]), str![[r#" Ok( ( [ 100, 101, 102, 103, ], [ 97, 98, 99, ], ), ) "#]] .raw() ); } #[test] fn opt_test() { fn opt_abcd<'i>(i: &mut Partial<&'i [u8]>) -> TestResult, Option<&'i [u8]>> { opt("abcd").parse_next(i) } let a = &b"abcdef"[..]; let b = &b"bcdefg"[..]; let c = &b"ab"[..]; assert_parse!( opt_abcd.parse_peek(Partial::new(a)), str![[r#" Ok( ( Partial { input: [ 101, 102, ], partial: true, }, Some( [ 97, 98, 99, 100, ], ), ), ) "#]] .raw() ); assert_parse!( opt_abcd.parse_peek(Partial::new(b)), str![[r#" Ok( ( Partial { input: [ 98, 99, 100, 101, 102, 103, ], partial: true, }, None, ), ) "#]] .raw() ); assert_parse!( opt_abcd.parse_peek(Partial::new(c)), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); } #[test] fn peek_test() { fn peek_literal<'i>(i: &mut Partial<&'i [u8]>) -> TestResult, &'i [u8]> { peek("abcd").parse_next(i) } assert_parse!( peek_literal.parse_peek(Partial::new(&b"abcdef"[..])), str![[r#" Ok( ( Partial { input: [ 97, 98, 99, 100, 101, 102, ], partial: true, }, [ 97, 98, 99, 100, ], ), ) "#]] .raw() ); assert_parse!( peek_literal.parse_peek(Partial::new(&b"ab"[..])), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); assert_parse!( peek_literal.parse_peek(Partial::new(&b"xxx"[..])), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 120, 120, 120, ], partial: true, }, }, ), ) "#]] .raw() ); } #[test] fn not_test() { fn not_aaa<'i>(i: &mut Partial<&'i [u8]>) -> TestResult, ()> { not("aaa").parse_next(i) } assert_parse!( not_aaa.parse_peek(Partial::new(&b"aaa"[..])), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 97, 97, 97, ], partial: true, }, }, ), ) "#]] .raw() ); assert_parse!( not_aaa.parse_peek(Partial::new(&b"aa"[..])), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); assert_parse!( not_aaa.parse_peek(Partial::new(&b"abcd"[..])), str![[r#" Ok( ( Partial { input: [ 97, 98, 99, 100, ], partial: true, }, (), ), ) "#]] .raw() ); } #[test] fn test_parser_verify() { use crate::token::take; fn test<'i>(i: &mut Partial<&'i [u8]>) -> TestResult, &'i [u8]> { take(5u8) .verify(|slice: &[u8]| slice[0] == b'a') .parse_next(i) } assert_parse!( test.parse_peek(Partial::new(&b"bcd"[..])), str![[r#" Err( Incomplete( Size( 2, ), ), ) "#]] .raw() ); assert_parse!( test.parse_peek(Partial::new(&b"bcdefg"[..])), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 98, 99, 100, 101, 102, 103, ], partial: true, }, }, ), ) "#]] .raw() ); assert_parse!( test.parse_peek(Partial::new(&b"abcdefg"[..])), str![[r#" Ok( ( Partial { input: [ 102, 103, ], partial: true, }, [ 97, 98, 99, 100, 101, ], ), ) "#]] .raw() ); } #[test] #[allow(unused)] fn test_parser_verify_ref() { use crate::token::take; let mut parser1 = take(3u8).verify(|s: &[u8]| s == &b"abc"[..]); assert_parse!( parser1.parse_peek(&b"abcd"[..]), str![[r#" Ok( ( [ 100, ], [ 97, 98, 99, ], ), ) "#]] .raw() ); assert_parse!( parser1.parse_peek(&b"defg"[..]), str![[r#" Err( Backtrack( InputError { input: [ 100, 101, 102, 103, ], }, ), ) "#]] .raw() ); fn parser2<'i>(i: &mut &'i [u8]) -> TestResult<&'i [u8], u32> { crate::binary::be_u32 .verify(|val: &u32| *val < 3) .parse_next(i) } } #[test] #[cfg(feature = "alloc")] fn test_parser_verify_alloc() { use crate::token::take; let mut parser1 = take(3u8) .map(|s: &[u8]| s.to_vec()) .verify(|s: &[u8]| s == &b"abc"[..]); assert_parse!( parser1.parse_peek(&b"abcd"[..]), str![[r#" Ok( ( [ 100, ], [ 97, 98, 99, ], ), ) "#]] .raw() ); assert_parse!( parser1.parse_peek(&b"defg"[..]), str![[r#" Err( Backtrack( InputError { input: [ 100, 101, 102, 103, ], }, ), ) "#]] .raw() ); } #[test] fn fail_test() { let a = "string"; let b = "another string"; assert_parse!( fail::<_, &str, _>.parse_peek(a), str![[r#" Err( Backtrack( InputError { input: "string", }, ), ) "#]] .raw() ); assert_parse!( fail::<_, &str, _>.parse_peek(b), str![[r#" Err( Backtrack( InputError { input: "another string", }, ), ) "#]] .raw() ); } #[test] fn complete() { fn err_test<'i>(i: &mut &'i [u8]) -> TestResult<&'i [u8], &'i [u8]> { let _ = "ijkl".parse_next(i)?; "mnop".parse_next(i) } let a = &b"ijklmn"[..]; let res_a = err_test.parse_peek(a); assert_parse!( res_a, str![[r#" Err( Backtrack( InputError { input: [ 109, 110, ], }, ), ) "#]] .raw() ); } #[test] fn separated_pair_test() { #[allow(clippy::type_complexity)] fn sep_pair_abc_def<'i>( i: &mut Partial<&'i [u8]>, ) -> TestResult, (&'i [u8], &'i [u8])> { separated_pair("abc", ",", "def").parse_next(i) } assert_parse!( sep_pair_abc_def.parse_peek(Partial::new(&b"abc,defghijkl"[..])), str![[r#" Ok( ( Partial { input: [ 103, 104, 105, 106, 107, 108, ], partial: true, }, ( [ 97, 98, 99, ], [ 100, 101, 102, ], ), ), ) "#]] .raw() ); assert_parse!( sep_pair_abc_def.parse_peek(Partial::new(&b"ab"[..])), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); assert_parse!( sep_pair_abc_def.parse_peek(Partial::new(&b"abc,d"[..])), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); assert_parse!( sep_pair_abc_def.parse_peek(Partial::new(&b"xxx"[..])), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 120, 120, 120, ], partial: true, }, }, ), ) "#]] .raw() ); assert_parse!( sep_pair_abc_def.parse_peek(Partial::new(&b"xxx,def"[..])), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 120, 120, 120, 44, 100, 101, 102, ], partial: true, }, }, ), ) "#]] .raw() ); assert_parse!( sep_pair_abc_def.parse_peek(Partial::new(&b"abc,xxx"[..])), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 120, 120, 120, ], partial: true, }, }, ), ) "#]] .raw() ); } #[test] fn preceded_test() { fn preceded_abcd_efgh<'i>( i: &mut Partial<&'i [u8]>, ) -> TestResult, &'i [u8]> { preceded("abcd", "efgh").parse_next(i) } assert_parse!( preceded_abcd_efgh.parse_peek(Partial::new(&b"abcdefghijkl"[..])), str![[r#" Ok( ( Partial { input: [ 105, 106, 107, 108, ], partial: true, }, [ 101, 102, 103, 104, ], ), ) "#]] .raw() ); assert_parse!( preceded_abcd_efgh.parse_peek(Partial::new(&b"ab"[..])), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); assert_parse!( preceded_abcd_efgh.parse_peek(Partial::new(&b"abcde"[..])), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); assert_parse!( preceded_abcd_efgh.parse_peek(Partial::new(&b"xxx"[..])), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 120, 120, 120, ], partial: true, }, }, ), ) "#]] .raw() ); assert_parse!( preceded_abcd_efgh.parse_peek(Partial::new(&b"xxxxdef"[..])), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 120, 120, 120, 120, 100, 101, 102, ], partial: true, }, }, ), ) "#]] .raw() ); assert_parse!( preceded_abcd_efgh.parse_peek(Partial::new(&b"abcdxxx"[..])), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 120, 120, 120, ], partial: true, }, }, ), ) "#]] .raw() ); } #[test] fn terminated_test() { fn terminated_abcd_efgh<'i>( i: &mut Partial<&'i [u8]>, ) -> TestResult, &'i [u8]> { terminated("abcd", "efgh").parse_next(i) } assert_parse!( terminated_abcd_efgh.parse_peek(Partial::new(&b"abcdefghijkl"[..])), str![[r#" Ok( ( Partial { input: [ 105, 106, 107, 108, ], partial: true, }, [ 97, 98, 99, 100, ], ), ) "#]] .raw() ); assert_parse!( terminated_abcd_efgh.parse_peek(Partial::new(&b"ab"[..])), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); assert_parse!( terminated_abcd_efgh.parse_peek(Partial::new(&b"abcde"[..])), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); assert_parse!( terminated_abcd_efgh.parse_peek(Partial::new(&b"xxx"[..])), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 120, 120, 120, ], partial: true, }, }, ), ) "#]] .raw() ); assert_parse!( terminated_abcd_efgh.parse_peek(Partial::new(&b"xxxxdef"[..])), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 120, 120, 120, 120, 100, 101, 102, ], partial: true, }, }, ), ) "#]] .raw() ); assert_parse!( terminated_abcd_efgh.parse_peek(Partial::new(&b"abcdxxxx"[..])), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 120, 120, 120, 120, ], partial: true, }, }, ), ) "#]] .raw() ); } #[test] fn delimited_test() { fn delimited_abc_def_ghi<'i>( i: &mut Partial<&'i [u8]>, ) -> TestResult, &'i [u8]> { delimited("abc", "def", "ghi").parse_next(i) } assert_parse!( delimited_abc_def_ghi.parse_peek(Partial::new(&b"abcdefghijkl"[..])), str![[r#" Ok( ( Partial { input: [ 106, 107, 108, ], partial: true, }, [ 100, 101, 102, ], ), ) "#]] .raw() ); assert_parse!( delimited_abc_def_ghi.parse_peek(Partial::new(&b"ab"[..])), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); assert_parse!( delimited_abc_def_ghi.parse_peek(Partial::new(&b"abcde"[..])), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); assert_parse!( delimited_abc_def_ghi.parse_peek(Partial::new(&b"abcdefgh"[..])), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); assert_parse!( delimited_abc_def_ghi.parse_peek(Partial::new(&b"xxx"[..])), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 120, 120, 120, ], partial: true, }, }, ), ) "#]] .raw() ); assert_parse!( delimited_abc_def_ghi.parse_peek(Partial::new(&b"xxxdefghi"[..])), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 120, 120, 120, 100, 101, 102, 103, 104, 105, ], partial: true, }, }, ), ) "#]] .raw() ); assert_parse!( delimited_abc_def_ghi.parse_peek(Partial::new(&b"abcxxxghi"[..])), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 120, 120, 120, 103, 104, 105, ], partial: true, }, }, ), ) "#]] .raw() ); assert_parse!( delimited_abc_def_ghi.parse_peek(Partial::new(&b"abcdefxxx"[..])), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 120, 120, 120, ], partial: true, }, }, ), ) "#]] .raw() ); } #[cfg(feature = "alloc")] #[test] fn alt_test() { #[cfg(feature = "alloc")] use crate::{ error::ParserError, lib::std::{fmt::Debug, string::String}, }; #[cfg(feature = "alloc")] #[derive(Debug, Clone, Eq, PartialEq)] struct ErrorStr(String); #[cfg(feature = "alloc")] impl From for ErrorStr { fn from(i: u32) -> Self { ErrorStr(format!("custom error code: {i}")) } } #[cfg(feature = "alloc")] impl<'a> From<&'a str> for ErrorStr { fn from(i: &'a str) -> Self { ErrorStr(format!("custom error message: {i}")) } } #[cfg(feature = "alloc")] impl ParserError for ErrorStr { type Inner = Self; fn from_input(input: &I) -> Self { ErrorStr(format!("custom error message: ({input:?})")) } fn append(self, input: &I, _: &::Checkpoint) -> Self { ErrorStr(format!("custom error message: ({input:?}) - {self:?}")) } fn into_inner(self) -> Result { Ok(self) } } fn work<'i>(input: &mut &'i [u8]) -> ModalResult<&'i [u8], ErrorStr> { Ok(input.finish()) } #[allow(unused_variables)] fn dont_work<'i>(input: &mut &'i [u8]) -> ModalResult<&'i [u8], ErrorStr> { Err(ErrMode::Backtrack(ErrorStr("abcd".to_owned()))) } fn work2<'i>(_input: &mut &'i [u8]) -> ModalResult<&'i [u8], ErrorStr> { Ok(&b""[..]) } fn alt1<'i>(i: &mut &'i [u8]) -> ModalResult<&'i [u8], ErrorStr> { alt((dont_work, dont_work)).parse_next(i) } fn alt2<'i>(i: &mut &'i [u8]) -> ModalResult<&'i [u8], ErrorStr> { alt((dont_work, work)).parse_next(i) } fn alt3<'i>(i: &mut &'i [u8]) -> ModalResult<&'i [u8], ErrorStr> { alt((dont_work, dont_work, work2, dont_work)).parse_next(i) } //named!(alt1, alt!(dont_work | dont_work)); //named!(alt2, alt!(dont_work | work)); //named!(alt3, alt!(dont_work | dont_work | work2 | dont_work)); let a = &b"abcd"[..]; assert_eq!( alt1.parse_peek(a), Err(ErrMode::Backtrack(ErrorStr( "custom error message: ([97, 98, 99, 100]) - ErrorStr(\"abcd\")".to_owned() ))) ); assert_eq!(alt2.parse_peek(a), Ok((&b""[..], a))); assert_eq!(alt3.parse_peek(a), Ok((a, &b""[..]))); fn alt4<'i>(i: &mut &'i [u8]) -> TestResult<&'i [u8], &'i [u8]> { alt(("abcd", "efgh")).parse_next(i) } let b = &b"efgh"[..]; assert_parse!( alt4.parse_peek(a), str![[r#" Ok( ( [], [ 97, 98, 99, 100, ], ), ) "#]] .raw() ); assert_parse!( alt4.parse_peek(b), str![[r#" Ok( ( [], [ 101, 102, 103, 104, ], ), ) "#]] .raw() ); } #[test] fn alt_incomplete() { fn alt1<'i>(i: &mut Partial<&'i [u8]>) -> TestResult, &'i [u8]> { alt(("a", "bc", "def")).parse_next(i) } let a = &b""[..]; assert_parse!( alt1.parse_peek(Partial::new(a)), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); let a = &b"b"[..]; assert_parse!( alt1.parse_peek(Partial::new(a)), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); let a = &b"bcd"[..]; assert_parse!( alt1.parse_peek(Partial::new(a)), str![[r#" Ok( ( Partial { input: [ 100, ], partial: true, }, [ 98, 99, ], ), ) "#]] .raw() ); let a = &b"cde"[..]; assert_parse!( alt1.parse_peek(Partial::new(a)), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 99, 100, 101, ], partial: true, }, }, ), ) "#]] .raw() ); let a = &b"de"[..]; assert_parse!( alt1.parse_peek(Partial::new(a)), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); let a = &b"defg"[..]; assert_parse!( alt1.parse_peek(Partial::new(a)), str![[r#" Ok( ( Partial { input: [ 103, ], partial: true, }, [ 100, 101, 102, ], ), ) "#]] .raw() ); } #[test] fn alt_array() { fn alt1<'i>(i: &mut &'i [u8]) -> TestResult<&'i [u8], &'i [u8]> { alt(["a", "bc", "def"]).parse_next(i) } let i = &b"a"[..]; assert_parse!( alt1.parse_peek(i), str![[r#" Ok( ( [], [ 97, ], ), ) "#]] .raw() ); let i = &b"bc"[..]; assert_parse!( alt1.parse_peek(i), str![[r#" Ok( ( [], [ 98, 99, ], ), ) "#]] .raw() ); let i = &b"defg"[..]; assert_parse!( alt1.parse_peek(i), str![[r#" Ok( ( [ 103, ], [ 100, 101, 102, ], ), ) "#]] .raw() ); let i = &b"z"[..]; assert_parse!( alt1.parse_peek(i), str![[r#" Err( Backtrack( InputError { input: [ 122, ], }, ), ) "#]] .raw() ); } #[test] fn alt_dynamic_array() { fn alt1<'i>(i: &mut &'i [u8]) -> TestResult<&'i [u8], &'i [u8]> { alt(&mut ["a", "bc", "def"][..]).parse_next(i) } let a = &b"a"[..]; assert_parse!( alt1.parse_peek(a), str![[r#" Ok( ( [], [ 97, ], ), ) "#]] .raw() ); let bc = &b"bc"[..]; assert_parse!( alt1.parse_peek(bc), str![[r#" Ok( ( [], [ 98, 99, ], ), ) "#]] .raw() ); let defg = &b"defg"[..]; assert_parse!( alt1.parse_peek(defg), str![[r#" Ok( ( [ 103, ], [ 100, 101, 102, ], ), ) "#]] .raw() ); } #[test] fn permutation_test() { #[allow(clippy::type_complexity)] fn perm<'i>( i: &mut Partial<&'i [u8]>, ) -> TestResult, (&'i [u8], &'i [u8], &'i [u8])> { permutation(("abcd", "efg", "hi")).parse_next(i) } let a = &b"abcdefghijk"[..]; assert_parse!( perm.parse_peek(Partial::new(a)), str![[r#" Ok( ( Partial { input: [ 106, 107, ], partial: true, }, ( [ 97, 98, 99, 100, ], [ 101, 102, 103, ], [ 104, 105, ], ), ), ) "#]] .raw() ); let b = &b"efgabcdhijk"[..]; assert_parse!( perm.parse_peek(Partial::new(b)), str![[r#" Ok( ( Partial { input: [ 106, 107, ], partial: true, }, ( [ 97, 98, 99, 100, ], [ 101, 102, 103, ], [ 104, 105, ], ), ), ) "#]] .raw() ); let c = &b"hiefgabcdjk"[..]; assert_parse!( perm.parse_peek(Partial::new(c)), str![[r#" Ok( ( Partial { input: [ 106, 107, ], partial: true, }, ( [ 97, 98, 99, 100, ], [ 101, 102, 103, ], [ 104, 105, ], ), ), ) "#]] .raw() ); let d = &b"efgxyzabcdefghi"[..]; assert_parse!( perm.parse_peek(Partial::new(d)), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 120, 121, 122, 97, 98, 99, 100, 101, 102, 103, 104, 105, ], partial: true, }, }, ), ) "#]] .raw() ); let e = &b"efgabc"[..]; assert_parse!( perm.parse_peek(Partial::new(e)), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); } #[test] #[cfg(feature = "alloc")] fn separated0_test() { fn multi<'i>(i: &mut Partial<&'i [u8]>) -> TestResult, Vec<&'i [u8]>> { separated(0.., "abcd", ",").parse_next(i) } fn multi_empty<'i>(i: &mut Partial<&'i [u8]>) -> TestResult, Vec<&'i [u8]>> { separated(0.., "", ",").parse_next(i) } fn multi_longsep<'i>( i: &mut Partial<&'i [u8]>, ) -> TestResult, Vec<&'i [u8]>> { separated(0.., "abcd", "..").parse_next(i) } let a = &b"abcdef"[..]; let b = &b"abcd,abcdef"[..]; let c = &b"azerty"[..]; let d = &b",,abc"[..]; let e = &b"abcd,abcd,ef"[..]; let f = &b"abc"[..]; let g = &b"abcd."[..]; let h = &b"abcd,abc"[..]; assert_parse!( multi.parse_peek(Partial::new(a)), str![[r#" Ok( ( Partial { input: [ 101, 102, ], partial: true, }, [ [ 97, 98, 99, 100, ], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(b)), str![[r#" Ok( ( Partial { input: [ 101, 102, ], partial: true, }, [ [ 97, 98, 99, 100, ], [ 97, 98, 99, 100, ], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(c)), str![[r#" Ok( ( Partial { input: [ 97, 122, 101, 114, 116, 121, ], partial: true, }, [], ), ) "#]] .raw() ); assert_parse!( multi_empty.parse_peek(Partial::new(d)), str![[r#" Ok( ( Partial { input: [ 97, 98, 99, ], partial: true, }, [ [], [], [], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(e)), str![[r#" Ok( ( Partial { input: [ 44, 101, 102, ], partial: true, }, [ [ 97, 98, 99, 100, ], [ 97, 98, 99, 100, ], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(f)), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); assert_parse!( multi_longsep.parse_peek(Partial::new(g)), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(h)), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); } #[test] #[cfg(feature = "alloc")] #[cfg_attr(debug_assertions, should_panic)] fn separated0_empty_sep_test() { fn empty_sep<'i>(i: &mut Partial<&'i [u8]>) -> TestResult, Vec<&'i [u8]>> { separated(0.., "abc", "").parse_next(i) } let i = &b"abcabc"[..]; assert_parse!( empty_sep.parse_peek(Partial::new(i)), str![[r#" Err( Cut( InputError { input: Partial { input: [ 97, 98, 99, ], partial: true, }, }, ), ) "#]] ); } #[test] #[cfg(feature = "alloc")] fn separated1_test() { fn multi<'i>(i: &mut Partial<&'i [u8]>) -> TestResult, Vec<&'i [u8]>> { separated(1.., "abcd", ",").parse_next(i) } fn multi_longsep<'i>( i: &mut Partial<&'i [u8]>, ) -> TestResult, Vec<&'i [u8]>> { separated(1.., "abcd", "..").parse_next(i) } let a = &b"abcdef"[..]; let b = &b"abcd,abcdef"[..]; let c = &b"azerty"[..]; let d = &b"abcd,abcd,ef"[..]; let f = &b"abc"[..]; let g = &b"abcd."[..]; let h = &b"abcd,abc"[..]; assert_parse!( multi.parse_peek(Partial::new(a)), str![[r#" Ok( ( Partial { input: [ 101, 102, ], partial: true, }, [ [ 97, 98, 99, 100, ], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(b)), str![[r#" Ok( ( Partial { input: [ 101, 102, ], partial: true, }, [ [ 97, 98, 99, 100, ], [ 97, 98, 99, 100, ], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(c)), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 97, 122, 101, 114, 116, 121, ], partial: true, }, }, ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(d)), str![[r#" Ok( ( Partial { input: [ 44, 101, 102, ], partial: true, }, [ [ 97, 98, 99, 100, ], [ 97, 98, 99, 100, ], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(f)), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); assert_parse!( multi_longsep.parse_peek(Partial::new(g)), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(h)), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); } #[test] #[cfg(feature = "alloc")] fn separated_test() { fn multi<'i>(i: &mut Partial<&'i [u8]>) -> TestResult, Vec<&'i [u8]>> { separated(2..=4, "abcd", ",").parse_next(i) } let a = &b"abcd,ef"[..]; let b = &b"abcd,abcd,efgh"[..]; let c = &b"abcd,abcd,abcd,abcd,efgh"[..]; let d = &b"abcd,abcd,abcd,abcd,abcd,efgh"[..]; let e = &b"abcd,ab"[..]; assert_parse!( multi.parse_peek(Partial::new(a)), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 101, 102, ], partial: true, }, }, ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(b)), str![[r#" Ok( ( Partial { input: [ 44, 101, 102, 103, 104, ], partial: true, }, [ [ 97, 98, 99, 100, ], [ 97, 98, 99, 100, ], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(c)), str![[r#" Ok( ( Partial { input: [ 44, 101, 102, 103, 104, ], partial: true, }, [ [ 97, 98, 99, 100, ], [ 97, 98, 99, 100, ], [ 97, 98, 99, 100, ], [ 97, 98, 99, 100, ], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(d)), str![[r#" Ok( ( Partial { input: [ 44, 97, 98, 99, 100, 44, 101, 102, 103, 104, ], partial: true, }, [ [ 97, 98, 99, 100, ], [ 97, 98, 99, 100, ], [ 97, 98, 99, 100, ], [ 97, 98, 99, 100, ], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(e)), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); } #[test] #[cfg(feature = "alloc")] fn repeat0_test() { fn multi<'i>(i: &mut Partial<&'i [u8]>) -> TestResult, Vec<&'i [u8]>> { repeat(0.., "abcd").parse_next(i) } assert_parse!( multi.parse_peek(Partial::new(&b"abcdef"[..])), str![[r#" Ok( ( Partial { input: [ 101, 102, ], partial: true, }, [ [ 97, 98, 99, 100, ], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(&b"abcdabcdefgh"[..])), str![[r#" Ok( ( Partial { input: [ 101, 102, 103, 104, ], partial: true, }, [ [ 97, 98, 99, 100, ], [ 97, 98, 99, 100, ], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(&b"azerty"[..])), str![[r#" Ok( ( Partial { input: [ 97, 122, 101, 114, 116, 121, ], partial: true, }, [], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(&b"abcdab"[..])), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(&b"abcd"[..])), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(&b""[..])), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); } #[test] #[cfg(feature = "alloc")] #[cfg_attr(debug_assertions, should_panic)] fn repeat0_empty_test() { fn multi_empty<'i>(i: &mut Partial<&'i [u8]>) -> TestResult, Vec<&'i [u8]>> { repeat(0.., "").parse_next(i) } assert_parse!( multi_empty.parse_peek(Partial::new(&b"abcdef"[..])), str![[r#" Err( Cut( InputError { input: Partial { input: [ 97, 98, 99, 100, 101, 102, ], partial: true, }, }, ), ) "#]] ); } #[test] #[cfg(feature = "alloc")] fn repeat1_test() { fn multi<'i>(i: &mut Partial<&'i [u8]>) -> TestResult, Vec<&'i [u8]>> { repeat(1.., "abcd").parse_next(i) } let a = &b"abcdef"[..]; let b = &b"abcdabcdefgh"[..]; let c = &b"azerty"[..]; let d = &b"abcdab"[..]; assert_parse!( multi.parse_peek(Partial::new(a)), str![[r#" Ok( ( Partial { input: [ 101, 102, ], partial: true, }, [ [ 97, 98, 99, 100, ], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(b)), str![[r#" Ok( ( Partial { input: [ 101, 102, 103, 104, ], partial: true, }, [ [ 97, 98, 99, 100, ], [ 97, 98, 99, 100, ], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(c)), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 97, 122, 101, 114, 116, 121, ], partial: true, }, }, ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(d)), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); } #[test] #[cfg(feature = "alloc")] fn repeat_till_test() { #[allow(clippy::type_complexity)] fn multi<'i>(i: &mut &'i [u8]) -> TestResult<&'i [u8], (Vec<&'i [u8]>, &'i [u8])> { repeat_till(0.., "abcd", "efgh").parse_next(i) } let a = b"abcdabcdefghabcd"; let b = b"efghabcd"; let c = b"azerty"; assert_parse!( multi.parse_peek(&a[..]), str![[r#" Ok( ( [ 97, 98, 99, 100, ], ( [ [ 97, 98, 99, 100, ], [ 97, 98, 99, 100, ], ], [ 101, 102, 103, 104, ], ), ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(&b[..]), str![[r#" Ok( ( [ 97, 98, 99, 100, ], ( [], [ 101, 102, 103, 104, ], ), ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(&c[..]), str![[r#" Err( Backtrack( InputError { input: [ 97, 122, 101, 114, 116, 121, ], }, ), ) "#]] .raw() ); } #[test] #[cfg(feature = "alloc")] fn repeat_till_range_test() { #[allow(clippy::type_complexity)] fn multi<'i>(i: &mut &'i str) -> TestResult<&'i str, (Vec<&'i str>, &'i str)> { repeat_till(2..=4, "ab", "cd").parse_next(i) } assert_parse!( multi.parse_peek("cd"), str![[r#" Err( Backtrack( InputError { input: "cd", }, ), ) "#]] .raw() ); assert_parse!( multi.parse_peek("abcd"), str![[r#" Err( Backtrack( InputError { input: "cd", }, ), ) "#]] .raw() ); assert_parse!( multi.parse_peek("ababcd"), str![[r#" Ok( ( "", ( [ "ab", "ab", ], "cd", ), ), ) "#]] .raw() ); assert_parse!( multi.parse_peek("abababcd"), str![[r#" Ok( ( "", ( [ "ab", "ab", "ab", ], "cd", ), ), ) "#]] .raw() ); assert_parse!( multi.parse_peek("ababababcd"), str![[r#" Ok( ( "", ( [ "ab", "ab", "ab", "ab", ], "cd", ), ), ) "#]] .raw() ); assert_parse!( multi.parse_peek("abababababcd"), str![[r#" Err( Backtrack( InputError { input: "abcd", }, ), ) "#]] .raw() ); } #[test] #[cfg(feature = "std")] fn infinite_many() { fn tst<'i>(input: &mut &'i [u8]) -> TestResult<&'i [u8], &'i [u8]> { println!("input: {input:?}"); Err(ParserError::from_input(input)) } // should not go into an infinite loop fn multi0<'i>(i: &mut &'i [u8]) -> TestResult<&'i [u8], Vec<&'i [u8]>> { repeat(0.., tst).parse_next(i) } let a = &b"abcdef"[..]; assert_parse!( multi0.parse_peek(a), str![[r#" Ok( ( [ 97, 98, 99, 100, 101, 102, ], [], ), ) "#]] .raw() ); fn multi1<'i>(i: &mut &'i [u8]) -> TestResult<&'i [u8], Vec<&'i [u8]>> { repeat(1.., tst).parse_next(i) } let a = &b"abcdef"[..]; assert_parse!( multi1.parse_peek(a), str![[r#" Err( Backtrack( InputError { input: [ 97, 98, 99, 100, 101, 102, ], }, ), ) "#]] .raw() ); } #[test] #[cfg(feature = "alloc")] fn repeat_test() { fn multi<'i>(i: &mut Partial<&'i [u8]>) -> TestResult, Vec<&'i [u8]>> { repeat(2..=4, "Abcd").parse_next(i) } let a = &b"Abcdef"[..]; let b = &b"AbcdAbcdefgh"[..]; let c = &b"AbcdAbcdAbcdAbcdefgh"[..]; let d = &b"AbcdAbcdAbcdAbcdAbcdefgh"[..]; let e = &b"AbcdAb"[..]; assert_parse!( multi.parse_peek(Partial::new(a)), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 101, 102, ], partial: true, }, }, ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(b)), str![[r#" Ok( ( Partial { input: [ 101, 102, 103, 104, ], partial: true, }, [ [ 65, 98, 99, 100, ], [ 65, 98, 99, 100, ], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(c)), str![[r#" Ok( ( Partial { input: [ 101, 102, 103, 104, ], partial: true, }, [ [ 65, 98, 99, 100, ], [ 65, 98, 99, 100, ], [ 65, 98, 99, 100, ], [ 65, 98, 99, 100, ], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(d)), str![[r#" Ok( ( Partial { input: [ 65, 98, 99, 100, 101, 102, 103, 104, ], partial: true, }, [ [ 65, 98, 99, 100, ], [ 65, 98, 99, 100, ], [ 65, 98, 99, 100, ], [ 65, 98, 99, 100, ], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(e)), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); } #[test] #[cfg(feature = "alloc")] fn count_test() { const TIMES: usize = 2; fn cnt_2<'i>(i: &mut Partial<&'i [u8]>) -> TestResult, Vec<&'i [u8]>> { repeat(TIMES, "abc").parse_next(i) } assert_parse!( cnt_2.parse_peek(Partial::new(&b"abcabcabcdef"[..])), str![[r#" Ok( ( Partial { input: [ 97, 98, 99, 100, 101, 102, ], partial: true, }, [ [ 97, 98, 99, ], [ 97, 98, 99, ], ], ), ) "#]] .raw() ); assert_parse!( cnt_2.parse_peek(Partial::new(&b"ab"[..])), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); assert_parse!( cnt_2.parse_peek(Partial::new(&b"abcab"[..])), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); assert_parse!( cnt_2.parse_peek(Partial::new(&b"xxx"[..])), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 120, 120, 120, ], partial: true, }, }, ), ) "#]] .raw() ); assert_parse!( cnt_2.parse_peek(Partial::new(&b"xxxabcabcdef"[..])), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 120, 120, 120, 97, 98, 99, 97, 98, 99, 100, 101, 102, ], partial: true, }, }, ), ) "#]] .raw() ); assert_parse!( cnt_2.parse_peek(Partial::new(&b"abcxxxabcdef"[..])), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 120, 120, 120, 97, 98, 99, 100, 101, 102, ], partial: true, }, }, ), ) "#]] .raw() ); } #[test] #[cfg(feature = "alloc")] fn count_zero() { const TIMES: usize = 0; fn counter_2<'i>(i: &mut &'i [u8]) -> TestResult<&'i [u8], Vec<&'i [u8]>> { repeat(TIMES, "abc").parse_next(i) } let done = &b"abcabcabcdef"[..]; let incomplete_1 = &b"ab"[..]; let incomplete_2 = &b"abcab"[..]; let error = &b"xxx"[..]; let error_1 = &b"xxxabcabcdef"[..]; let error_2 = &b"abcxxxabcdef"[..]; assert_parse!( counter_2.parse_peek(done), str![[r#" Ok( ( [ 97, 98, 99, 97, 98, 99, 97, 98, 99, 100, 101, 102, ], [], ), ) "#]] .raw() ); assert_parse!( counter_2.parse_peek(incomplete_1), str![[r#" Ok( ( [ 97, 98, ], [], ), ) "#]] .raw() ); assert_parse!( counter_2.parse_peek(incomplete_2), str![[r#" Ok( ( [ 97, 98, 99, 97, 98, ], [], ), ) "#]] .raw() ); assert_parse!( counter_2.parse_peek(error), str![[r#" Ok( ( [ 120, 120, 120, ], [], ), ) "#]] .raw() ); assert_parse!( counter_2.parse_peek(error_1), str![[r#" Ok( ( [ 120, 120, 120, 97, 98, 99, 97, 98, 99, 100, 101, 102, ], [], ), ) "#]] .raw() ); assert_parse!( counter_2.parse_peek(error_2), str![[r#" Ok( ( [ 97, 98, 99, 120, 120, 120, 97, 98, 99, 100, 101, 102, ], [], ), ) "#]] .raw() ); } #[derive(Debug, Clone, Eq, PartialEq)] struct NilError; impl ParserError for NilError { type Inner = Self; fn from_input(_: &I) -> NilError { NilError } fn into_inner(self) -> Result { Ok(self) } } #[test] #[cfg(feature = "alloc")] fn fold_repeat0_test() { fn fold_into_vec(mut acc: Vec, item: T) -> Vec { acc.push(item); acc } fn multi<'i>(i: &mut Partial<&'i [u8]>) -> TestResult, Vec<&'i [u8]>> { repeat(0.., "abcd") .fold(Vec::new, fold_into_vec) .parse_next(i) } assert_parse!( multi.parse_peek(Partial::new(&b"abcdef"[..])), str![[r#" Ok( ( Partial { input: [ 101, 102, ], partial: true, }, [ [ 97, 98, 99, 100, ], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(&b"abcdabcdefgh"[..])), str![[r#" Ok( ( Partial { input: [ 101, 102, 103, 104, ], partial: true, }, [ [ 97, 98, 99, 100, ], [ 97, 98, 99, 100, ], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(&b"azerty"[..])), str![[r#" Ok( ( Partial { input: [ 97, 122, 101, 114, 116, 121, ], partial: true, }, [], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(&b"abcdab"[..])), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(&b"abcd"[..])), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(&b""[..])), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); } #[test] #[cfg(feature = "alloc")] #[cfg_attr(debug_assertions, should_panic)] fn fold_repeat0_empty_test() { fn fold_into_vec(mut acc: Vec, item: T) -> Vec { acc.push(item); acc } fn multi_empty<'i>(i: &mut Partial<&'i [u8]>) -> TestResult, Vec<&'i [u8]>> { repeat(0.., "").fold(Vec::new, fold_into_vec).parse_next(i) } assert_parse!( multi_empty.parse_peek(Partial::new(&b"abcdef"[..])), str![[r#" Err( Cut( InputError { input: Partial { input: [ 97, 98, 99, 100, 101, 102, ], partial: true, }, }, ), ) "#]] ); } #[test] #[cfg(feature = "alloc")] fn fold_repeat1_test() { fn fold_into_vec(mut acc: Vec, item: T) -> Vec { acc.push(item); acc } fn multi<'i>(i: &mut Partial<&'i [u8]>) -> TestResult, Vec<&'i [u8]>> { repeat(1.., "abcd") .fold(Vec::new, fold_into_vec) .parse_next(i) } let a = &b"abcdef"[..]; let b = &b"abcdabcdefgh"[..]; let c = &b"azerty"[..]; let d = &b"abcdab"[..]; assert_parse!( multi.parse_peek(Partial::new(a)), str![[r#" Ok( ( Partial { input: [ 101, 102, ], partial: true, }, [ [ 97, 98, 99, 100, ], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(b)), str![[r#" Ok( ( Partial { input: [ 101, 102, 103, 104, ], partial: true, }, [ [ 97, 98, 99, 100, ], [ 97, 98, 99, 100, ], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(c)), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 97, 122, 101, 114, 116, 121, ], partial: true, }, }, ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(d)), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); } #[test] #[cfg(feature = "alloc")] fn fold_repeat_test() { fn fold_into_vec(mut acc: Vec, item: T) -> Vec { acc.push(item); acc } fn multi<'i>(i: &mut Partial<&'i [u8]>) -> TestResult, Vec<&'i [u8]>> { repeat(2..=4, "Abcd") .fold(Vec::new, fold_into_vec) .parse_next(i) } let a = &b"Abcdef"[..]; let b = &b"AbcdAbcdefgh"[..]; let c = &b"AbcdAbcdAbcdAbcdefgh"[..]; let d = &b"AbcdAbcdAbcdAbcdAbcdefgh"[..]; let e = &b"AbcdAb"[..]; assert_parse!( multi.parse_peek(Partial::new(a)), str![[r#" Err( Backtrack( InputError { input: Partial { input: [ 101, 102, ], partial: true, }, }, ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(b)), str![[r#" Ok( ( Partial { input: [ 101, 102, 103, 104, ], partial: true, }, [ [ 65, 98, 99, 100, ], [ 65, 98, 99, 100, ], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(c)), str![[r#" Ok( ( Partial { input: [ 101, 102, 103, 104, ], partial: true, }, [ [ 65, 98, 99, 100, ], [ 65, 98, 99, 100, ], [ 65, 98, 99, 100, ], [ 65, 98, 99, 100, ], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(d)), str![[r#" Ok( ( Partial { input: [ 65, 98, 99, 100, 101, 102, 103, 104, ], partial: true, }, [ [ 65, 98, 99, 100, ], [ 65, 98, 99, 100, ], [ 65, 98, 99, 100, ], [ 65, 98, 99, 100, ], ], ), ) "#]] .raw() ); assert_parse!( multi.parse_peek(Partial::new(e)), str![[r#" Err( Incomplete( Unknown, ), ) "#]] .raw() ); } #[test] fn repeat0_count_test() { fn count0_nums<'i>(i: &mut &'i [u8]) -> TestResult<&'i [u8], usize> { repeat(0.., (digit, ",")).parse_next(i) } assert_parse!( count0_nums.parse_peek(&b"123,junk"[..]), str![[r#" Ok( ( [ 106, 117, 110, 107, ], 1, ), ) "#]] .raw() ); assert_parse!( count0_nums.parse_peek(&b"123,45,junk"[..]), str![[r#" Ok( ( [ 106, 117, 110, 107, ], 2, ), ) "#]] .raw() ); assert_parse!( count0_nums.parse_peek(&b"1,2,3,4,5,6,7,8,9,0,junk"[..]), str![[r#" Ok( ( [ 106, 117, 110, 107, ], 10, ), ) "#]] .raw() ); assert_parse!( count0_nums.parse_peek(&b"hello"[..]), str![[r#" Ok( ( [ 104, 101, 108, 108, 111, ], 0, ), ) "#]] .raw() ); } #[test] fn repeat1_count_test() { fn count1_nums<'i>(i: &mut &'i [u8]) -> TestResult<&'i [u8], usize> { repeat(1.., (digit, ",")).parse_next(i) } assert_parse!( count1_nums.parse_peek(&b"123,45,junk"[..]), str![[r#" Ok( ( [ 106, 117, 110, 107, ], 2, ), ) "#]] .raw() ); assert_parse!( count1_nums.parse_peek(&b"1,2,3,4,5,6,7,8,9,0,junk"[..]), str![[r#" Ok( ( [ 106, 117, 110, 107, ], 10, ), ) "#]] .raw() ); assert_parse!( count1_nums.parse_peek(&b"hello"[..]), str![[r#" Err( Backtrack( InputError { input: [ 104, 101, 108, 108, 111, ], }, ), ) "#]] .raw() ); }