blob: 4286286ae82b0f68878b014a8f735b174ec5e9b6 [file] [log] [blame]
use super::*;
use crate::bytes::take;
use crate::error::ErrMode;
use crate::error::Error;
use crate::error::ErrorKind;
use crate::error::Needed;
use crate::error::ParseError;
use crate::multi::count;
use crate::number::u16;
use crate::number::u8;
use crate::number::Endianness;
use crate::IResult;
use crate::Parser;
use crate::Partial;
macro_rules! assert_parse(
($left: expr, $right: expr) => {
let res: $crate::IResult<_, _, Error<_>> = $left;
assert_eq!(res, $right);
};
);
#[test]
fn eof_on_slices() {
let not_over: &[u8] = &b"Hello, world!"[..];
let is_over: &[u8] = &b""[..];
let res_not_over = eof(not_over);
assert_parse!(
res_not_over,
Err(ErrMode::Backtrack(error_position!(
not_over,
ErrorKind::Eof
)))
);
let res_over = eof(is_over);
assert_parse!(res_over, Ok((is_over, is_over)));
}
#[test]
fn eof_on_strs() {
let not_over: &str = "Hello, world!";
let is_over: &str = "";
let res_not_over = eof(not_over);
assert_parse!(
res_not_over,
Err(ErrMode::Backtrack(error_position!(
not_over,
ErrorKind::Eof
)))
);
let res_over = eof(is_over);
assert_parse!(res_over, Ok((is_over, is_over)));
}
#[test]
fn rest_on_slices() {
let input: &[u8] = &b"Hello, world!"[..];
let empty: &[u8] = &b""[..];
assert_parse!(rest(input), Ok((empty, input)));
}
#[test]
fn rest_on_strs() {
let input: &str = "Hello, world!";
let empty: &str = "";
assert_parse!(rest(input), Ok((empty, input)));
}
#[test]
fn rest_len_on_slices() {
let input: &[u8] = &b"Hello, world!"[..];
assert_parse!(rest_len(input), Ok((input, input.len())));
}
use crate::lib::std::convert::From;
impl From<u32> for CustomError {
fn from(_: u32) -> Self {
CustomError
}
}
impl<I> ParseError<I> for CustomError {
fn from_error_kind(_: I, _: ErrorKind) -> Self {
CustomError
}
fn append(self, _: I, _: ErrorKind) -> Self {
CustomError
}
}
struct CustomError;
#[allow(dead_code)]
fn custom_error(input: &[u8]) -> IResult<&[u8], &[u8], CustomError> {
//fix_error!(input, CustomError<_>, alphanumeric)
crate::character::alphanumeric1(input)
}
#[test]
fn test_parser_flat_map() {
let input: &[u8] = &[3, 100, 101, 102, 103, 104][..];
assert_parse!(
u8.flat_map(take).parse_next(input),
Ok((&[103, 104][..], &[100, 101, 102][..]))
);
}
#[allow(dead_code)]
fn test_closure_compiles_195(input: &[u8]) -> IResult<&[u8], ()> {
u8.flat_map(|num| count(u16(Endianness::Big), num as usize))
.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_next(input),
Err(ErrMode::Backtrack(Error {
input: &[50][..],
kind: ErrorKind::Verify
}))
);
assert_parse!(
u8.verify_map(|u| if u > 20 { Some(u) } else { None })
.parse_next(input),
Ok((&[][..], 50))
);
}
#[test]
fn test_parser_map_parser() {
let input: &[u8] = &[100, 101, 102, 103, 104][..];
assert_parse!(
take(4usize).and_then(take(2usize)).parse_next(input),
Ok((&[104][..], &[100, 101][..]))
);
}
#[test]
#[cfg(feature = "std")]
fn test_parser_into() {
use crate::bytes::take;
use crate::error::Error;
let mut parser = take::<_, _, Error<_>>(3u8).output_into();
let result: IResult<&[u8], Vec<u8>> = parser.parse_next(&b"abcdefg"[..]);
assert_eq!(result, Ok((&b"defg"[..], vec![97, 98, 99])));
}
#[test]
fn opt_test() {
fn opt_abcd(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Option<&[u8]>> {
opt("abcd").parse_next(i)
}
let a = &b"abcdef"[..];
let b = &b"bcdefg"[..];
let c = &b"ab"[..];
assert_eq!(
opt_abcd(Partial::new(a)),
Ok((Partial::new(&b"ef"[..]), Some(&b"abcd"[..])))
);
assert_eq!(
opt_abcd(Partial::new(b)),
Ok((Partial::new(&b"bcdefg"[..]), None))
);
assert_eq!(
opt_abcd(Partial::new(c)),
Err(ErrMode::Incomplete(Needed::new(2)))
);
}
#[test]
fn peek_test() {
fn peek_tag(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> {
peek("abcd").parse_next(i)
}
assert_eq!(
peek_tag(Partial::new(&b"abcdef"[..])),
Ok((Partial::new(&b"abcdef"[..]), &b"abcd"[..]))
);
assert_eq!(
peek_tag(Partial::new(&b"ab"[..])),
Err(ErrMode::Incomplete(Needed::new(2)))
);
assert_eq!(
peek_tag(Partial::new(&b"xxx"[..])),
Err(ErrMode::Backtrack(error_position!(
Partial::new(&b"xxx"[..]),
ErrorKind::Tag
)))
);
}
#[test]
fn not_test() {
fn not_aaa(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, ()> {
not("aaa").parse_next(i)
}
assert_eq!(
not_aaa(Partial::new(&b"aaa"[..])),
Err(ErrMode::Backtrack(error_position!(
Partial::new(&b"aaa"[..]),
ErrorKind::Not
)))
);
assert_eq!(
not_aaa(Partial::new(&b"aa"[..])),
Err(ErrMode::Incomplete(Needed::new(1)))
);
assert_eq!(
not_aaa(Partial::new(&b"abcd"[..])),
Ok((Partial::new(&b"abcd"[..]), ()))
);
}
#[test]
fn test_parser_verify() {
use crate::bytes::take;
fn test(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> {
take(5u8)
.verify(|slice: &[u8]| slice[0] == b'a')
.parse_next(i)
}
assert_eq!(
test(Partial::new(&b"bcd"[..])),
Err(ErrMode::Incomplete(Needed::new(2)))
);
assert_eq!(
test(Partial::new(&b"bcdefg"[..])),
Err(ErrMode::Backtrack(error_position!(
Partial::new(&b"bcdefg"[..]),
ErrorKind::Verify
)))
);
assert_eq!(
test(Partial::new(&b"abcdefg"[..])),
Ok((Partial::new(&b"fg"[..]), &b"abcde"[..]))
);
}
#[test]
#[allow(unused)]
fn test_parser_verify_ref() {
use crate::bytes::take;
let mut parser1 = take(3u8).verify(|s: &[u8]| s == &b"abc"[..]);
assert_eq!(
parser1.parse_next(&b"abcd"[..]),
Ok((&b"d"[..], &b"abc"[..]))
);
assert_eq!(
parser1.parse_next(&b"defg"[..]),
Err(ErrMode::Backtrack(Error {
input: &b"defg"[..],
kind: ErrorKind::Verify
}))
);
fn parser2(i: &[u8]) -> IResult<&[u8], u32> {
crate::number::be_u32
.verify(|val: &u32| *val < 3)
.parse_next(i)
}
}
#[test]
#[cfg(feature = "alloc")]
fn test_parser_verify_alloc() {
use crate::bytes::take;
let mut parser1 = take(3u8)
.map(|s: &[u8]| s.to_vec())
.verify(|s: &[u8]| s == &b"abc"[..]);
assert_eq!(
parser1.parse_next(&b"abcd"[..]),
Ok((&b"d"[..], b"abc".to_vec()))
);
assert_eq!(
parser1.parse_next(&b"defg"[..]),
Err(ErrMode::Backtrack(Error {
input: &b"defg"[..],
kind: ErrorKind::Verify
}))
);
}
#[test]
fn fail_test() {
let a = "string";
let b = "another string";
assert_eq!(
fail::<_, &str, _>(a),
Err(ErrMode::Backtrack(Error {
input: a,
kind: ErrorKind::Fail
}))
);
assert_eq!(
fail::<_, &str, _>(b),
Err(ErrMode::Backtrack(Error {
input: b,
kind: ErrorKind::Fail
}))
);
}