2015-12-31 12:23:09 +00:00
|
|
|
//#![feature(trace_macros)]
|
2017-06-16 12:34:49 +00:00
|
|
|
#![allow(dead_code)]
|
2017-12-10 13:03:25 +00:00
|
|
|
#![cfg_attr(feature = "cargo-clippy", allow(redundant_closure))]
|
2017-06-16 12:34:49 +00:00
|
|
|
|
2015-08-04 07:07:55 +00:00
|
|
|
#[macro_use]
|
|
|
|
extern crate nom;
|
|
|
|
|
2019-04-26 14:22:16 +00:00
|
|
|
use nom::{character::{is_digit, streaming::space1 as space}, Err, IResult, Needed, error::ErrorKind, number::streaming::le_u64};
|
2015-08-04 07:07:55 +00:00
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
struct Range {
|
|
|
|
start: char,
|
2018-02-25 12:12:11 +00:00
|
|
|
end: char,
|
2015-08-04 07:07:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn take_char(input: &[u8]) -> IResult<&[u8], char> {
|
2017-12-10 13:03:25 +00:00
|
|
|
if !input.is_empty() {
|
2017-09-07 12:28:33 +00:00
|
|
|
Ok((&input[1..], input[0] as char))
|
2015-08-04 07:07:55 +00:00
|
|
|
} else {
|
2017-09-07 12:28:33 +00:00
|
|
|
Err(Err::Incomplete(Needed::Size(1)))
|
2015-08-04 07:07:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//trace_macros!(true);
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
named!(range<&[u8], Range>,
|
|
|
|
alt!(
|
2016-10-18 10:28:58 +00:00
|
|
|
do_parse!(
|
|
|
|
start: take_char >>
|
|
|
|
tag!("-") >>
|
|
|
|
end: take_char >>
|
|
|
|
(Range {
|
|
|
|
start: start,
|
|
|
|
end: end,
|
|
|
|
})
|
2015-08-04 07:07:55 +00:00
|
|
|
) |
|
|
|
|
map!(
|
|
|
|
take_char,
|
|
|
|
|c| {
|
|
|
|
Range {
|
|
|
|
start: c,
|
2016-10-18 10:28:58 +00:00
|
|
|
end: c,
|
2015-08-04 07:07:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
named!(literal<&[u8], Vec<char> >,
|
|
|
|
map!(
|
|
|
|
many1!(take_char),
|
|
|
|
|cs| {
|
|
|
|
cs
|
|
|
|
}
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn issue_58() {
|
2017-12-09 15:12:57 +00:00
|
|
|
let _ = range(&b"abcd"[..]);
|
|
|
|
let _ = literal(&b"abcd"[..]);
|
2015-08-04 07:07:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//trace_macros!(false);
|
2015-12-30 15:24:10 +00:00
|
|
|
|
2017-05-09 11:00:21 +00:00
|
|
|
#[cfg(feature = "std")]
|
|
|
|
mod parse_int {
|
|
|
|
use nom::HexDisplay;
|
2019-04-26 14:22:16 +00:00
|
|
|
use nom::{IResult, character::streaming::{digit1 as digit, space1 as space}};
|
2017-05-09 11:00:21 +00:00
|
|
|
use std::str;
|
|
|
|
|
2018-02-17 14:06:43 +00:00
|
|
|
named!(parse_ints<Vec<i32>>, many0!(spaces_or_int));
|
2017-05-09 11:00:21 +00:00
|
|
|
|
2017-12-10 17:39:11 +00:00
|
|
|
fn spaces_or_int(input: &[u8]) -> IResult<&[u8], i32> {
|
2017-05-09 11:00:21 +00:00
|
|
|
println!("{}", input.to_hex(8));
|
2018-02-17 14:06:43 +00:00
|
|
|
do_parse!(
|
|
|
|
input,
|
|
|
|
opt!(complete!(space)) >> res: map!(complete!(digit), |x| {
|
2017-05-09 11:00:21 +00:00
|
|
|
println!("x: {:?}", x);
|
|
|
|
let result = str::from_utf8(x).unwrap();
|
|
|
|
println!("Result: {}", result);
|
|
|
|
println!("int is empty?: {}", x.is_empty());
|
2018-02-17 14:06:43 +00:00
|
|
|
match result.parse() {
|
2017-05-09 11:00:21 +00:00
|
|
|
Ok(i) => i,
|
2018-02-17 14:06:43 +00:00
|
|
|
Err(e) => panic!("UH OH! NOT A DIGIT! {:?}", e),
|
2017-05-09 11:00:21 +00:00
|
|
|
}
|
2018-02-17 14:06:43 +00:00
|
|
|
}) >> (res)
|
2017-05-09 11:00:21 +00:00
|
|
|
)
|
|
|
|
}
|
2015-12-30 15:24:10 +00:00
|
|
|
|
2017-05-09 11:00:21 +00:00
|
|
|
#[test]
|
2017-12-10 17:39:11 +00:00
|
|
|
fn issue_142() {
|
2018-01-11 18:29:46 +00:00
|
|
|
let subject = parse_ints(&b"12 34 5689a"[..]);
|
|
|
|
let expected = Ok((&b"a"[..], vec![12, 34, 5689]));
|
2017-12-10 17:39:11 +00:00
|
|
|
assert_eq!(subject, expected);
|
|
|
|
|
|
|
|
let subject = parse_ints(&b"12 34 5689 "[..]);
|
|
|
|
let expected = Ok((&b" "[..], vec![12, 34, 5689]));
|
|
|
|
assert_eq!(subject, expected)
|
2017-05-09 11:00:21 +00:00
|
|
|
}
|
2015-12-30 15:24:10 +00:00
|
|
|
}
|
2015-12-31 12:23:09 +00:00
|
|
|
|
2016-03-28 08:07:03 +00:00
|
|
|
#[test]
|
2017-12-10 17:39:11 +00:00
|
|
|
fn usize_length_bytes_issue() {
|
2019-04-15 14:53:57 +00:00
|
|
|
use nom::number::streaming::be_u16;
|
2019-05-06 13:48:56 +00:00
|
|
|
let _: IResult<&[u8], &[u8], (&[u8], ErrorKind)> = length_data!(b"012346", be_u16);
|
2016-03-28 08:07:03 +00:00
|
|
|
}
|
|
|
|
|
2015-12-31 12:23:09 +00:00
|
|
|
/*
|
|
|
|
DOES NOT COMPILE
|
|
|
|
#[test]
|
|
|
|
fn issue_152() {
|
|
|
|
named!(take4, take!(4));
|
|
|
|
named!(xyz, tag!("XYZ"));
|
|
|
|
named!(abc, tag!("abc"));
|
|
|
|
|
|
|
|
|
|
|
|
named!(sw,
|
|
|
|
switch!(take4,
|
|
|
|
b"abcd" => xyz |
|
|
|
|
b"efgh" => abc
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
*/
|
2016-04-11 21:59:50 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn take_till_issue() {
|
2018-02-17 14:06:43 +00:00
|
|
|
named!(nothing, take_till!(call!(|_| true)));
|
2016-04-11 21:59:50 +00:00
|
|
|
|
2018-01-11 14:36:51 +00:00
|
|
|
assert_eq!(nothing(b""), Err(Err::Incomplete(Needed::Size(1))));
|
2017-12-10 17:39:11 +00:00
|
|
|
assert_eq!(nothing(b"abc"), Ok((&b"abc"[..], &b""[..])));
|
2016-04-11 21:59:50 +00:00
|
|
|
}
|
2017-05-09 14:10:53 +00:00
|
|
|
|
2018-02-17 14:06:43 +00:00
|
|
|
named!(
|
|
|
|
issue_498<Vec<&[u8]>>,
|
|
|
|
separated_nonempty_list!(opt!(space), tag!("abcd"))
|
|
|
|
);
|
2017-05-09 14:10:53 +00:00
|
|
|
|
|
|
|
named!(issue_308(&str) -> bool,
|
|
|
|
do_parse! (
|
2019-03-23 13:18:55 +00:00
|
|
|
tag! ("foo") >>
|
2019-05-08 17:06:03 +00:00
|
|
|
b: alt! (
|
|
|
|
complete!(map! (tag! ("1"), |_: &str|->bool {true})) |
|
2017-05-09 14:10:53 +00:00
|
|
|
value! (false)
|
|
|
|
) >>
|
|
|
|
(b) ));
|
|
|
|
|
2018-02-05 22:18:40 +00:00
|
|
|
#[cfg(feature = "alloc")]
|
2017-12-10 17:39:11 +00:00
|
|
|
fn issue_302(input: &[u8]) -> IResult<&[u8], Option<Vec<u64>>> {
|
2018-02-17 14:06:43 +00:00
|
|
|
do_parse!(input, entries: cond!(true, count!(le_u64, 3)) >> (entries))
|
2017-05-09 14:10:53 +00:00
|
|
|
}
|
2018-01-15 11:07:51 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn issue_655() {
|
2019-04-15 14:53:57 +00:00
|
|
|
use nom::character::streaming::{line_ending, not_line_ending};
|
2018-01-15 11:07:51 +00:00
|
|
|
named!(twolines(&str) -> (&str, &str),
|
|
|
|
do_parse!(
|
|
|
|
l1 : not_line_ending >>
|
|
|
|
line_ending >>
|
|
|
|
l2 : not_line_ending >>
|
|
|
|
line_ending >>
|
|
|
|
((l1, l2))
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
assert_eq!(twolines("foo\nbar\n"), Ok(("", ("foo", "bar"))));
|
|
|
|
assert_eq!(twolines("féo\nbar\n"), Ok(("", ("féo", "bar"))));
|
|
|
|
assert_eq!(twolines("foé\nbar\n"), Ok(("", ("foé", "bar"))));
|
|
|
|
assert_eq!(twolines("foé\r\nbar\n"), Ok(("", ("foé", "bar"))));
|
|
|
|
}
|
2018-01-24 15:36:09 +00:00
|
|
|
|
2018-03-21 11:03:49 +00:00
|
|
|
#[test]
|
|
|
|
fn issue_721() {
|
2019-04-09 07:23:34 +00:00
|
|
|
named!(f1<&str, u16>, parse_to!(u16));
|
|
|
|
named!(f2<&str, String>, parse_to!(String));
|
|
|
|
assert_eq!(f1("1234"), Ok(("", 1234)));
|
|
|
|
assert_eq!(f2("foo"), Ok(("", "foo".to_string())));
|
|
|
|
//assert_eq!(parse_to!("1234", u16), Ok(("", 1234)));
|
|
|
|
//assert_eq!(parse_to!("foo", String), Ok(("", "foo".to_string())));
|
2018-03-26 09:09:58 +00:00
|
|
|
}
|
|
|
|
|
2018-04-03 22:26:46 +00:00
|
|
|
#[cfg(feature = "alloc")]
|
2018-03-26 09:09:58 +00:00
|
|
|
named!(issue_717<&[u8], Vec<&[u8]> >,
|
|
|
|
separated_list!(tag!([0x0]), is_not!([0x0u8]))
|
|
|
|
);
|
2018-03-26 09:21:59 +00:00
|
|
|
|
|
|
|
struct NoPartialEq {
|
2018-03-28 08:55:32 +00:00
|
|
|
value: i32,
|
2018-03-26 09:21:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
named!(issue_724<&str, i32>,
|
|
|
|
do_parse!(
|
|
|
|
metadata: permutation!(
|
|
|
|
map!(tag!("hello"), |_| NoPartialEq { value: 1 }),
|
|
|
|
map!(tag!("world"), |_| NoPartialEq { value: 2 })
|
|
|
|
) >>
|
|
|
|
(metadata.0.value + metadata.1.value)
|
|
|
|
)
|
|
|
|
);
|
2018-04-23 12:08:30 +00:00
|
|
|
|
2018-07-19 18:17:54 +00:00
|
|
|
#[test]
|
|
|
|
fn issue_752() {
|
|
|
|
assert_eq!(
|
2019-04-15 14:53:57 +00:00
|
|
|
Err::Error(("ab", nom::error::ErrorKind::ParseTo)),
|
2018-10-14 13:11:23 +00:00
|
|
|
parse_to!("ab", usize).unwrap_err()
|
2018-07-19 18:17:54 +00:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2018-05-19 09:47:19 +00:00
|
|
|
fn atom_specials(c: u8) -> bool {
|
|
|
|
c == b'q'
|
|
|
|
}
|
|
|
|
|
|
|
|
named!(
|
|
|
|
capability<&str>,
|
2019-03-23 13:18:55 +00:00
|
|
|
do_parse!(tag!(" ") >> _atom: map_res!(take_till1!(atom_specials), std::str::from_utf8) >> ("a"))
|
2018-05-19 09:47:19 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn issue_759() {
|
|
|
|
assert_eq!(capability(b" abcqd"), Ok((&b"qd"[..], "a")));
|
|
|
|
}
|
2018-05-19 09:52:47 +00:00
|
|
|
|
|
|
|
named_args!(issue_771(count: usize)<Vec<u32>>,
|
2019-04-15 14:53:57 +00:00
|
|
|
length_count!(value!(count), call!(nom::number::streaming::be_u32))
|
2018-05-19 09:52:47 +00:00
|
|
|
);
|
2018-05-25 15:27:11 +00:00
|
|
|
|
2018-05-27 22:24:27 +00:00
|
|
|
/// This test is in a separate module to check that all required symbols are imported in
|
|
|
|
/// `escaped_transform!()`. Without the module, the `use`-es of the current module would
|
|
|
|
/// mask the error ('"Use of undeclared type or module `Needed`" in escaped_transform!').
|
|
|
|
mod issue_780 {
|
|
|
|
named!(issue_780<&str, String>,
|
2019-04-26 14:22:16 +00:00
|
|
|
escaped_transform!(call!(::nom::character::streaming::alpha1), '\\', tag!("n"))
|
2018-05-27 22:24:27 +00:00
|
|
|
);
|
|
|
|
}
|
2018-08-18 16:04:45 +00:00
|
|
|
|
|
|
|
// issue 617
|
|
|
|
named!(digits, take_while1!( is_digit ));
|
|
|
|
named!(multi_617<&[u8], () >, fold_many0!( digits, (), |_, _| {}));
|
|
|
|
|
|
|
|
// Sad :(
|
|
|
|
named!(multi_617_fails<&[u8], () >, fold_many0!( take_while1!( is_digit ), (), |_, _| {}));
|
|
|
|
|
|
|
|
mod issue_647 {
|
2019-04-15 14:53:57 +00:00
|
|
|
use nom::{Err, number::streaming::be_f64, error::ErrorKind};
|
2018-08-18 16:04:45 +00:00
|
|
|
pub type Input<'a> = &'a [u8];
|
|
|
|
|
|
|
|
#[derive(PartialEq, Debug, Clone)]
|
|
|
|
struct Data {
|
|
|
|
c: f64,
|
|
|
|
v: Vec<f64>
|
|
|
|
}
|
|
|
|
|
2019-04-09 07:23:34 +00:00
|
|
|
fn list<'a,'b>(input: Input<'a>, _cs: &'b f64) -> Result<(Input<'a>,Vec<f64>), Err<(&'a [u8], ErrorKind)>> {
|
2019-05-08 17:06:03 +00:00
|
|
|
separated_list!(input, complete!(tag!(",")), complete!(be_f64))
|
2018-08-18 16:04:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
named!(data<Input,Data>, map!(
|
|
|
|
do_parse!(
|
|
|
|
c: be_f64 >>
|
|
|
|
tag!("\n") >>
|
|
|
|
v: call!(list,&c) >>
|
|
|
|
(c,v)
|
|
|
|
), |(c,v)| {
|
|
|
|
Data {
|
|
|
|
c: c,
|
|
|
|
v: v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
named!(issue_775, take_till1!(|_| true));
|
2018-12-26 18:22:18 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn issue_848_overflow_incomplete_bits_to_bytes() {
|
2019-06-17 14:12:06 +00:00
|
|
|
named!(take, take!(0x2000000000000000));
|
|
|
|
named!(parser<&[u8], &[u8]>, bits!(bytes!(take)));
|
2018-12-26 18:22:18 +00:00
|
|
|
assert_eq!(parser(&b""[..]), Err(Err::Failure(error_position!(&b""[..], ErrorKind::TooLarge))));
|
|
|
|
}
|
2019-05-05 08:48:28 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn issue_942() {
|
|
|
|
use nom::error::ParseError;
|
|
|
|
pub fn parser<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, usize, E> {
|
|
|
|
use nom::{character::complete::char, error::context, multi::many0_count};
|
|
|
|
many0_count(context("char_a", char('a')))(i)
|
|
|
|
}
|
|
|
|
assert_eq!(parser::<()>("aaa"), Ok(("", 3)));
|
|
|
|
}
|
2019-07-16 13:48:45 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn issue_many_m_n_with_zeros() {
|
|
|
|
use nom::multi::many_m_n;
|
|
|
|
use nom::character::complete::char;
|
|
|
|
let parser = many_m_n::<_, _, (), _>(0, 0, char('a'));
|
|
|
|
assert_eq!(parser("aaa"), Ok(("aaa", vec!())));
|
|
|
|
}
|
2019-09-13 20:46:29 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn issue_1027_convert_error_panic_nonempty() {
|
|
|
|
use nom::error::{VerboseError, convert_error};
|
|
|
|
use nom::sequence::pair;
|
|
|
|
use nom::character::complete::char;
|
|
|
|
|
|
|
|
let input = "a";
|
|
|
|
|
|
|
|
let result: IResult<_, _, VerboseError<&str>> = pair(char('a'), char('b'))(input);
|
|
|
|
let err = match result.unwrap_err() {
|
|
|
|
Err::Error(e) => e,
|
|
|
|
_ => unreachable!(),
|
|
|
|
};
|
|
|
|
|
|
|
|
let msg = convert_error(&input, err);
|
2020-01-07 18:11:19 +00:00
|
|
|
assert_eq!(msg, "0: at line 1:\na\n ^\nexpected \'b\', got end of input\n\n");
|
|
|
|
}
|