formatting

This commit is contained in:
Geoffroy Couprie 2020-04-10 11:01:58 +02:00
parent ac34e5ac11
commit afad7bf93e
61 changed files with 2571 additions and 1091 deletions

View File

@ -43,7 +43,8 @@ named!(
} else {
acc / val
}
) >> (res)
)
>> (res)
)
);
@ -60,7 +61,8 @@ named!(
} else {
acc - val
}
) >> (res)
)
>> (res)
)
);

View File

@ -9,17 +9,22 @@ static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
use criterion::*;
use nom::{
IResult,
bytes::complete::take_while,
character::complete::{
alphanumeric1 as alphanumeric, char, multispace1 as multispace, space1 as space,
},
combinator::map_res,
sequence::delimited,
bytes::complete::take_while,
character::complete::{alphanumeric1 as alphanumeric, multispace1 as multispace, space1 as space, char}
IResult,
};
use std::str;
use std::collections::HashMap;
use std::str;
fn category(i: &[u8]) -> IResult<&[u8], &str> {
map_res(delimited(char('['), take_while(|c| c != b']'), char(']')), str::from_utf8)(i)
map_res(
delimited(char('['), take_while(|c| c != b']'), char(']')),
str::from_utf8,
)(i)
}
named!(key_value <&[u8],(&str,&str)>,
@ -238,12 +243,10 @@ file=payroll.dat
c.bench(
"bench ini",
Benchmark::new(
"parse",
move |b| {
b.iter(|| categories(str.as_bytes()).unwrap());
},
).throughput(Throughput::Bytes(str.len() as u64)),
Benchmark::new("parse", move |b| {
b.iter(|| categories(str.as_bytes()).unwrap());
})
.throughput(Throughput::Bytes(str.len() as u64)),
);
}
@ -257,12 +260,10 @@ file=payroll.dat
c.bench(
"bench ini keys and values",
Benchmark::new(
"parse",
move |b| {
b.iter(|| acc(str.as_bytes()).unwrap());
},
).throughput(Throughput::Bytes(str.len() as u64)),
Benchmark::new("parse", move |b| {
b.iter(|| acc(str.as_bytes()).unwrap());
})
.throughput(Throughput::Bytes(str.len() as u64)),
);
}
@ -271,14 +272,17 @@ fn bench_ini_key_value(c: &mut Criterion) {
c.bench(
"bench ini key value",
Benchmark::new(
"parse",
move |b| {
b.iter(|| key_value(str.as_bytes()).unwrap());
},
).throughput(Throughput::Bytes(str.len() as u64)),
Benchmark::new("parse", move |b| {
b.iter(|| key_value(str.as_bytes()).unwrap());
})
.throughput(Throughput::Bytes(str.len() as u64)),
);
}
criterion_group!(benches, bench_ini, bench_ini_keys_and_values, bench_ini_key_value);
criterion_group!(
benches,
bench_ini,
bench_ini_keys_and_values,
bench_ini_key_value
);
criterion_main!(benches);

View File

@ -9,14 +9,16 @@ static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
use criterion::*;
use nom::{
IResult,
bytes::complete::take_while,
character::complete::{
alphanumeric1 as alphanumeric, char, multispace1 as multispace, space1 as space,
},
combinator::map_res,
sequence::delimited,
bytes::complete::take_while,
character::complete::{alphanumeric1 as alphanumeric, multispace1 as multispace, space1 as space, char}
IResult,
};
use std::str;
use std::collections::HashMap;
use std::str;
/*
named!(category<&[u8], &str>, map_res!(
@ -34,10 +36,13 @@ fn complete_byte_slice_to_str<'a>(s: &'a [u8]) -> Result<&'a str, str::Utf8Error
*/
fn category(i: &[u8]) -> IResult<&[u8], &str> {
map_res(delimited(char('['), take_while(|c| c != b']'), char(']')), str::from_utf8)(i)
map_res(
delimited(char('['), take_while(|c| c != b']'), char(']')),
str::from_utf8,
)(i)
}
fn complete_byte_slice_to_str<'a>(s: &'a[u8]) -> Result<&'a str, str::Utf8Error> {
fn complete_byte_slice_to_str<'a>(s: &'a [u8]) -> Result<&'a str, str::Utf8Error> {
str::from_utf8(s)
}
@ -254,12 +259,10 @@ file=payroll.dat
c.bench(
"bench ini complete",
Benchmark::new(
"parse",
move |b| {
b.iter(|| categories(s.as_bytes()).unwrap());
},
).throughput(Throughput::Bytes(s.len() as u64)),
Benchmark::new("parse", move |b| {
b.iter(|| categories(s.as_bytes()).unwrap());
})
.throughput(Throughput::Bytes(s.len() as u64)),
);
}
@ -273,12 +276,10 @@ file=payroll.dat
c.bench(
"bench ini complete keys and values",
Benchmark::new(
"parse",
move |b| {
b.iter(|| acc(s.as_bytes()).unwrap());
},
).throughput(Throughput::Bytes(s.len() as u64)),
Benchmark::new("parse", move |b| {
b.iter(|| acc(s.as_bytes()).unwrap());
})
.throughput(Throughput::Bytes(s.len() as u64)),
);
}
@ -287,14 +288,17 @@ fn bench_ini_complete_key_value(c: &mut Criterion) {
c.bench(
"bench ini complete key value",
Benchmark::new(
"parse",
move |b| {
b.iter(|| key_value(s.as_bytes()).unwrap());
},
).throughput(Throughput::Bytes(s.len() as u64)),
Benchmark::new("parse", move |b| {
b.iter(|| key_value(s.as_bytes()).unwrap());
})
.throughput(Throughput::Bytes(s.len() as u64)),
);
}
criterion_group!(benches, bench_ini_complete, bench_ini_complete_keys_and_values, bench_ini_complete_key_value);
criterion_group!(
benches,
bench_ini_complete,
bench_ini_complete_keys_and_values,
bench_ini_complete_key_value
);
criterion_main!(benches);

View File

@ -9,14 +9,13 @@ use criterion::*;
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
use nom::{
IResult,
bytes::complete::{is_a, take_while},
character::complete::{alphanumeric1 as alphanumeric, char, not_line_ending, space0 as space},
combinator::opt,
bytes::complete::{take_while, is_a},
sequence::{delimited, terminated},
character::complete::{char, alphanumeric1 as alphanumeric, space0 as space, not_line_ending}
IResult,
};
use std::collections::HashMap;
fn is_line_ending_or_comment(chr: char) -> bool {
@ -28,10 +27,12 @@ fn space_or_line_ending(i: &str) -> IResult<&str, &str> {
}
fn category(i: &str) -> IResult<&str, &str> {
terminated(delimited(char('['), take_while(|c| c != ']'), char(']')), opt(is_a(" \r\n")))(i)
terminated(
delimited(char('['), take_while(|c| c != ']'), char(']')),
opt(is_a(" \r\n")),
)(i)
}
named!(key_value <&str,(&str,&str)>,
do_parse!(
key: alphanumeric >>
@ -232,12 +233,10 @@ file=payroll.dat
c.bench(
"bench ini str",
Benchmark::new(
"parse",
move |b| {
b.iter(|| categories(s).unwrap());
},
).throughput(Throughput::Bytes(s.len() as u64)),
Benchmark::new("parse", move |b| {
b.iter(|| categories(s).unwrap());
})
.throughput(Throughput::Bytes(s.len() as u64)),
);
}

View File

@ -8,12 +8,14 @@ extern crate jemallocator;
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
use criterion::Criterion;
use nom::{error::ErrorKind, character::complete::alphanumeric1 as alphanumeric, number::complete::recognize_float};
use nom::number::complete::float;
use nom::{
character::complete::alphanumeric1 as alphanumeric, error::ErrorKind,
number::complete::recognize_float,
};
use std::str;
use std::collections::HashMap;
use std::str;
#[derive(Debug, PartialEq)]
pub enum JsonValue {
@ -75,12 +77,12 @@ named!(
named!(
value<JsonValue>,
ws!(alt!(
hash => { |h| JsonValue::Object(h) } |
array => { |v| JsonValue::Array(v) } |
string => { |s| JsonValue::Str(String::from(s)) } |
float => { |f| JsonValue::Num(f) } |
boolean => { |b| JsonValue::Boolean(b) }
))
hash => { |h| JsonValue::Object(h) } |
array => { |v| JsonValue::Array(v) } |
string => { |s| JsonValue::Str(String::from(s)) } |
float => { |f| JsonValue::Num(f) } |
boolean => { |b| JsonValue::Boolean(b) }
))
);
fn json_bench(c: &mut Criterion) {
@ -97,34 +99,53 @@ fn json_bench(c: &mut Criterion) {
}
fn recognize_float_bytes(c: &mut Criterion) {
println!("recognize_float_bytes result: {:?}", recognize_float::<_, (_,ErrorKind)>(&b"-1.234E-12"[..]));
println!(
"recognize_float_bytes result: {:?}",
recognize_float::<_, (_, ErrorKind)>(&b"-1.234E-12"[..])
);
c.bench_function("recognize float bytes", |b| {
b.iter(|| recognize_float::<_, (_,ErrorKind)>(&b"-1.234E-12"[..]));
b.iter(|| recognize_float::<_, (_, ErrorKind)>(&b"-1.234E-12"[..]));
});
}
fn recognize_float_str(c: &mut Criterion) {
println!("recognize_float_str result: {:?}", recognize_float::<_, (_,ErrorKind)>("-1.234E-12"));
println!(
"recognize_float_str result: {:?}",
recognize_float::<_, (_, ErrorKind)>("-1.234E-12")
);
c.bench_function("recognize float str", |b| {
b.iter(|| recognize_float::<_, (_,ErrorKind)>("-1.234E-12"));
b.iter(|| recognize_float::<_, (_, ErrorKind)>("-1.234E-12"));
});
}
fn float_bytes(c: &mut Criterion) {
use nom::number::complete::double;
println!("float_bytes result: {:?}", double::<_, (_,ErrorKind)>(&b"-1.234E-12"[..]));
println!(
"float_bytes result: {:?}",
double::<_, (_, ErrorKind)>(&b"-1.234E-12"[..])
);
c.bench_function("float bytes", |b| {
b.iter(|| double::<_, (_,ErrorKind)>(&b"-1.234E-12"[..]));
b.iter(|| double::<_, (_, ErrorKind)>(&b"-1.234E-12"[..]));
});
}
fn float_str(c: &mut Criterion) {
use nom::number::complete::double;
println!("float_str result: {:?}", double::<_, (_,ErrorKind)>("-1.234E-12"));
println!(
"float_str result: {:?}",
double::<_, (_, ErrorKind)>("-1.234E-12")
);
c.bench_function("float str", |b| {
b.iter(|| double::<_, (_,ErrorKind)>("-1.234E-12"));
b.iter(|| double::<_, (_, ErrorKind)>("-1.234E-12"));
});
}
criterion_group!(benches, json_bench, recognize_float_bytes, recognize_float_str, float_bytes, float_str);
criterion_group!(
benches,
json_bench,
recognize_float_bytes,
recognize_float_str,
float_bytes,
float_str
);
criterion_main!(benches);

View File

@ -11,7 +11,7 @@ use criterion::Criterion;
use nom::number::{complete, streaming};
fn parser(i: &[u8]) -> nom::IResult<&[u8], u64> {
complete::be_u64(i)
complete::be_u64(i)
}
fn number(c: &mut Criterion) {

View File

@ -11,7 +11,7 @@ use nom::{
bytes::complete::{escaped, tag, take_while},
character::complete::{alphanumeric1 as alphanumeric, char, one_of},
combinator::{cut, map, opt, value},
error::{context, convert_error, ErrorKind, ParseError, VerboseError, ContextError},
error::{context, convert_error, ContextError, ErrorKind, ParseError, VerboseError},
multi::separated_list0,
number::complete::double,
sequence::{delimited, preceded, separated_pair, terminated},
@ -94,15 +94,22 @@ fn boolean<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, bool,
/// parsing the string
/// - `context` lets you add a static string to provide more information in the
/// error chain (to indicate which parser had an error)
fn string<'a, E: ParseError<&'a str> + ContextError<&'a str>>(i: &'a str) -> IResult<&'a str, &'a str, E> {
context("string", preceded(char('\"'), cut(terminated(parse_str, char('\"')))))(i)
fn string<'a, E: ParseError<&'a str> + ContextError<&'a str>>(
i: &'a str,
) -> IResult<&'a str, &'a str, E> {
context(
"string",
preceded(char('\"'), cut(terminated(parse_str, char('\"')))),
)(i)
}
/// some combinators, like `separated_list0` or `many0`, will call a parser repeatedly,
/// accumulating results in a `Vec`, until it encounters an error.
/// If you want more control on the parser application, check out the `iterator`
/// combinator (cf `examples/iterator.rs`)
fn array<'a, E: ParseError<&'a str> + ContextError<&'a str>>(i: &'a str) -> IResult<&'a str, Vec<JsonValue>, E> {
fn array<'a, E: ParseError<&'a str> + ContextError<&'a str>>(
i: &'a str,
) -> IResult<&'a str, Vec<JsonValue>, E> {
context(
"array",
preceded(
@ -115,19 +122,33 @@ fn array<'a, E: ParseError<&'a str> + ContextError<&'a str>>(i: &'a str) -> IRes
)(i)
}
fn key_value<'a, E: ParseError<&'a str> + ContextError<&'a str>>(i: &'a str) -> IResult<&'a str, (&'a str, JsonValue), E> {
separated_pair(preceded(sp, string), cut(preceded(sp, char(':'))), json_value)(i)
fn key_value<'a, E: ParseError<&'a str> + ContextError<&'a str>>(
i: &'a str,
) -> IResult<&'a str, (&'a str, JsonValue), E> {
separated_pair(
preceded(sp, string),
cut(preceded(sp, char(':'))),
json_value,
)(i)
}
fn hash<'a, E: ParseError<&'a str> + ContextError<&'a str>>(i: &'a str) -> IResult<&'a str, HashMap<String, JsonValue>, E> {
fn hash<'a, E: ParseError<&'a str> + ContextError<&'a str>>(
i: &'a str,
) -> IResult<&'a str, HashMap<String, JsonValue>, E> {
context(
"map",
preceded(
char('{'),
cut(terminated(
map(separated_list0(preceded(sp, char(',')), key_value), |tuple_vec| {
tuple_vec.into_iter().map(|(k, v)| (String::from(k), v)).collect()
}),
map(
separated_list0(preceded(sp, char(',')), key_value),
|tuple_vec| {
tuple_vec
.into_iter()
.map(|(k, v)| (String::from(k), v))
.collect()
},
),
preceded(sp, char('}')),
)),
),
@ -135,7 +156,9 @@ fn hash<'a, E: ParseError<&'a str> + ContextError<&'a str>>(i: &'a str) -> IResu
}
/// here, we apply the space parser before trying to parse a value
fn json_value<'a, E: ParseError<&'a str> + ContextError<&'a str>>(i: &'a str) -> IResult<&'a str, JsonValue, E> {
fn json_value<'a, E: ParseError<&'a str> + ContextError<&'a str>>(
i: &'a str,
) -> IResult<&'a str, JsonValue, E> {
preceded(
sp,
alt((
@ -149,8 +172,14 @@ fn json_value<'a, E: ParseError<&'a str> + ContextError<&'a str>>(i: &'a str) ->
}
/// the root element of a JSON parser is either an object or an array
fn root<'a, E: ParseError<&'a str> + ContextError<&'a str>>(i: &'a str) -> IResult<&'a str, JsonValue, E> {
delimited(sp, alt((map(hash, JsonValue::Object), map(array, JsonValue::Array))), opt(sp))(i)
fn root<'a, E: ParseError<&'a str> + ContextError<&'a str>>(
i: &'a str,
) -> IResult<&'a str, JsonValue, E> {
delimited(
sp,
alt((map(hash, JsonValue::Object), map(array, JsonValue::Array))),
opt(sp),
)(i)
}
fn main() {
@ -160,7 +189,10 @@ fn main() {
}
} ";
println!("will try to parse valid JSON data:\n\n**********\n{}\n**********\n", data);
println!(
"will try to parse valid JSON data:\n\n**********\n{}\n**********\n",
data
);
// this will print:
// Ok(
@ -195,7 +227,10 @@ fn main() {
// ),
// ),
// )
println!("parsing a valid file:\n{:#?}\n", root::<(&str, ErrorKind)>(data));
println!(
"parsing a valid file:\n{:#?}\n",
root::<(&str, ErrorKind)>(data)
);
let data = " { \"a\"\t: 42,
\"b\": [ \"x\", \"y\", 12 ] ,
@ -203,7 +238,10 @@ fn main() {
}
} ";
println!("will try to parse invalid JSON data:\n\n**********\n{}\n**********\n", data);
println!(
"will try to parse invalid JSON data:\n\n**********\n{}\n**********\n",
data
);
// here we use `(Input, ErrorKind)` as error type, which is used by default
// if you don't specify it. It contains the position of the error and some
@ -278,7 +316,10 @@ fn main() {
// 2: at line 0, in map:
// { "a" : 42,
// ^
println!("verbose errors - `root::<VerboseError>(data)`:\n{}", convert_error(data, e));
println!(
"verbose errors - `root::<VerboseError>(data)`:\n{}",
convert_error(data, e)
);
}
_ => {}
}

334
examples/json_iterator.rs Normal file
View File

@ -0,0 +1,334 @@
#![cfg(feature = "alloc")]
use jemallocator;
#[global_allocator]
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
use nom::{
branch::alt,
bytes::complete::{escaped, tag, take_while},
character::complete::{alphanumeric1 as alphanumeric, char, one_of},
combinator::{map, opt, cut},
error::{context, ErrorKind, ParseError},
error::{VerboseError, VerboseErrorKind},
multi::separated_list,
number::complete::double,
sequence::{delimited, preceded, separated_pair, terminated},
Err, IResult, Offset,
};
use std::collections::HashMap;
use std::str;
use std::cell::Cell;
struct Cursor<'a> {
inner: &'a str,
offset: usize,
}
#[derive(Clone, Debug)]
pub struct JsonValue<'a, 'b> {
input: &'a str,
pub offset: &'b Cell<usize>,
}
impl<'a, 'b:'a> JsonValue<'a, 'b> {
pub fn new(input: &'a str, offset: &'b Cell<usize>) -> JsonValue<'a, 'b> {
JsonValue { input, offset }
}
pub fn offset(&self, input: &'a str) {
let offset = input.as_ptr() as usize - self.input.as_ptr() as usize;
self.offset.set(offset);
}
pub fn data(&self) -> &'a str {
&self.input[self.offset.get()..]
}
pub fn string(&self) -> Option<&'a str> {
println!("string()");
match string(self.data()) {
Ok((i, s)) => {
self.offset(i);
println!("-> {}", s);
Some(s)
},
_ => None,
}
}
pub fn boolean(&self) -> Option<bool> {
println!("boolean()");
match boolean(self.data()) {
Ok((i, o)) => {
self.offset(i);
println!("-> {}", o);
Some(o)
},
_ => None,
}
}
pub fn number(&self) -> Option<f64> {
println!("number()");
match double::<_,()>(self.data()) {
Ok((i, o)) => {
self.offset(i);
println!("-> {}", o);
Some(o)
},
_ => None,
}
}
pub fn array(&self) -> Option<impl Iterator<Item=JsonValue<'a, 'b>>> {
println!("array()");
match tag::<_,_,()>("[")(self.data()) {
Err(_) => None,
Ok((i, _)) => {
println!("[");
self.offset(i);
let mut first = true;
let mut done = false;
let mut previous = std::usize::MAX;
let v = self.clone();
Some(std::iter::from_fn(move|| {
if done {
return None;
}
// if we ignored one of the items, skip over the value
if v.offset.get() == previous {
println!("skipping value");
match value(v.data()) {
Ok((i, _)) => {
v.offset(i);
},
Err(_) => {},
}
}
match tag::<_,_,()>("]")(v.data()) {
Ok((i, _)) => {
println!("]");
v.offset(i);
done = true;
return None;
},
Err(_) => {}
};
if first {
first = false;
} else {
match tag::<_,_,()>(",")(v.data()) {
Ok((i, _)) => {
println!(",");
v.offset(i);
},
Err(_) => {
done = true;
return None;
}
}
}
println!("-> {}", v.data());
previous = v.offset.get();
Some(v.clone())
}))
}
}
}
pub fn object(&self) -> Option<impl Iterator<Item=(&'a str, JsonValue<'a, 'b>)>> {
println!("object()");
match tag::<_,_,()>("{")(self.data()) {
Err(_) => None,
Ok((i, _)) => {
self.offset(i);
println!("{{");
let mut first = true;
let mut done = false;
let mut previous = std::usize::MAX;
let v = self.clone();
Some(std::iter::from_fn(move|| {
if done {
return None;
}
// if we ignored one of the items, skip over the value
if v.offset.get() == previous {
println!("skipping value");
match value(v.data()) {
Ok((i, _)) => {
v.offset(i);
},
Err(_) => {},
}
}
match tag::<_,_,()>("}")(v.data()) {
Ok((i, _)) => {
println!("}}");
v.offset(i);
done = true;
return None;
},
Err(_) => {}
};
if first {
first = false;
} else {
match tag::<_,_,()>(",")(v.data()) {
Ok((i, _)) => {
println!(",");
v.offset(i);
},
Err(_) => {
done = true;
return None;
}
}
}
match string(v.data()) {
Ok((i, key)) => {
v.offset(i);
match tag::<_,_,()>(":")(v.data()) {
Err(_) => None,
Ok((i, _)) => {
v.offset(i);
previous = v.offset.get();
println!("-> {} => {}", key, v.data());
Some((key, v.clone()))
}
}
},
_ => None,
}
}))
}
}
}
}
fn sp<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, &'a str, E> {
let chars = " \t\r\n";
take_while(move |c| chars.contains(c))(i)
}
fn parse_str<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, &'a str, E> {
escaped(alphanumeric, '\\', one_of("\"n\\"))(i)
}
fn string<'a>(i: &'a str) -> IResult<&'a str, &'a str> {
context("string",
preceded(
char('\"'),
cut(terminated(
parse_str,
char('\"')
))))(i)
}
fn boolean<'a>(input: &'a str) -> IResult<&'a str, bool> {
alt((
map(tag("false"), |_| false),
map(tag("true"), |_| true)
))(input)
}
fn array<'a>(i: &'a str) -> IResult<&'a str, ()> {
context(
"array",
preceded(char('['),
cut(terminated(
map(separated_list(preceded(sp, char(',')), value), |_| ()),
preceded(sp, char(']'))))
))(i)
}
fn key_value<'a>(i: &'a str) -> IResult<&'a str, (&'a str, ())> {
separated_pair(preceded(sp, string), cut(preceded(sp, char(':'))), value)(i)
}
fn hash<'a>(i: &'a str) -> IResult<&'a str, ()> {
context(
"map",
preceded(char('{'),
cut(terminated(
map(
separated_list(preceded(sp, char(',')), key_value),
|_| ()),
preceded(sp, char('}')),
))
))(i)
}
fn value<'a>(i: &'a str) -> IResult<&'a str, ()> {
preceded(
sp,
alt((
hash,
array,
map(string, |_| ()),
map(double, |_| ()),
map(boolean, |_| ()),
)),
)(i)
}
/// object(input) -> iterator over (key, JsonValue)
/// array(input) -> iterator over JsonValue
///
/// JsonValue.string -> iterator over String (returns None after first successful call)
///
/// object(input).filter(|(k, _)| k == "users").flatten(|(_, v)| v.object()).filter(|(k, _)| k == "city").flatten(|(_,v)| v.string())
fn main() {
/*let data = "{
\"users\": {
\"user1\" : { \"city\": \"Nantes\", \"country\": \"France\" },
\"user2\" : { \"city\": \"Bruxelles\", \"country\": \"Belgium\" },
\"user3\": { \"city\": \"Paris\", \"country\": \"France\", \"age\": 30 }
},
\"countries\": [\"France\", \"Belgium\"]
}";
*/
let data = "{\"users\":{\"user1\":{\"city\":\"Nantes\",\"country\":\"France\"},\"user2\":{\"city\":\"Bruxelles\",\"country\":\"Belgium\"},\"user3\":{\"city\":\"Paris\",\"country\":\"France\",\"age\":30}},\"countries\":[\"France\",\"Belgium\"]}";
let offset = Cell::new(0);
{
let parser = JsonValue::new(data, &offset);
if let Some(o) = parser.object() {
let s: HashMap<&str, &str> = o.filter(|(k,_)| *k == "users" )
.filter_map(|(_, v)| v.object()).flatten()
.filter_map(|(user, v)| v.object().map(|o| (user, o)))
.map(|(user, o)| {
o.filter(|(k,_)| *k == "city" )
.filter_map(move |(_, v)| v.string().map(|s| (user, s)))
}).flatten().collect();
println!("res = {:?}", s);
}
};
}

17
examples/macro.rs Normal file
View File

@ -0,0 +1,17 @@
#[macro_use]
extern crate nom;
use nom::{character::complete::digit0, number::complete::be_u32};
named!(first<u32>, flat_map!(digit0, parse_to!(u32)));
named!(second<u32>, call!(be_u32));
named!(parser<u32>, alt!(first | second));
fn main() {
let data = b"1234;";
let res = parser(&data[..]);
println!("res: {:?}", res);
}

View File

@ -103,7 +103,10 @@ fn parse_builtin<'a>(i: &'a str) -> IResult<&'a str, BuiltIn, VerboseError<&'a s
/// Our boolean values are also constant, so we can do it the same way
fn parse_bool<'a>(i: &'a str) -> IResult<&'a str, Atom, VerboseError<&'a str>> {
alt((map(tag("#t"), |_| Atom::Boolean(true)), map(tag("#f"), |_| Atom::Boolean(false))))(i)
alt((
map(tag("#t"), |_| Atom::Boolean(true)),
map(tag("#f"), |_| Atom::Boolean(false)),
))(i)
}
/// The next easiest thing to parse are keywords.
@ -113,16 +116,19 @@ fn parse_bool<'a>(i: &'a str) -> IResult<&'a str, Atom, VerboseError<&'a str>> {
/// Put plainly: `preceded(tag(":"), cut(alpha1))` means that once we see the `:`
/// character, we have to see one or more alphabetic chararcters or the input is invalid.
fn parse_keyword<'a>(i: &'a str) -> IResult<&'a str, Atom, VerboseError<&'a str>> {
map(context("keyword", preceded(tag(":"), cut(alpha1))), |sym_str: &str| {
Atom::Keyword(sym_str.to_string())
})(i)
map(
context("keyword", preceded(tag(":"), cut(alpha1))),
|sym_str: &str| Atom::Keyword(sym_str.to_string()),
)(i)
}
/// Next up is number parsing. We're keeping it simple here by accepting any number (> 1)
/// of digits but ending the program if it doesn't fit into an i32.
fn parse_num<'a>(i: &'a str) -> IResult<&'a str, Atom, VerboseError<&'a str>> {
alt((
map_res(digit1, |digit_str: &str| digit_str.parse::<i32>().map(Atom::Num)),
map_res(digit1, |digit_str: &str| {
digit_str.parse::<i32>().map(Atom::Num)
}),
map(preceded(tag("-"), digit1), |digit_str: &str| {
Atom::Num(-1 * digit_str.parse::<i32>().unwrap())
}),
@ -132,7 +138,12 @@ fn parse_num<'a>(i: &'a str) -> IResult<&'a str, Atom, VerboseError<&'a str>> {
/// Now we take all these simple parsers and connect them.
/// We can now parse half of our language!
fn parse_atom<'a>(i: &'a str) -> IResult<&'a str, Atom, VerboseError<&'a str>> {
alt((parse_num, parse_bool, map(parse_builtin, Atom::BuiltIn), parse_keyword))(i)
alt((
parse_num,
parse_bool,
map(parse_builtin, Atom::BuiltIn),
parse_keyword,
))(i)
}
/// We then add the Expr layer on top
@ -194,7 +205,11 @@ fn parse_if<'a>(i: &'a str) -> IResult<&'a str, Expr, VerboseError<&'a str>> {
),
|(pred, true_branch, maybe_false_branch)| {
if let Some(false_branch) = maybe_false_branch {
Expr::IfElse(Box::new(pred), Box::new(true_branch), Box::new(false_branch))
Expr::IfElse(
Box::new(pred),
Box::new(true_branch),
Box::new(false_branch),
)
} else {
Expr::If(Box::new(pred), Box::new(true_branch))
}
@ -213,15 +228,19 @@ fn parse_quote<'a>(i: &'a str) -> IResult<&'a str, Expr, VerboseError<&'a str>>
// this should look very straight-forward after all we've done:
// we find the `'` (quote) character, use cut to say that we're unambiguously
// looking for an s-expression of 0 or more expressions, and then parse them
map(context("quote", preceded(tag("'"), cut(s_exp(many0(parse_expr))))), |exprs| {
Expr::Quote(exprs)
})(i)
map(
context("quote", preceded(tag("'"), cut(s_exp(many0(parse_expr))))),
|exprs| Expr::Quote(exprs),
)(i)
}
/// We tie them all together again, making a top-level expression parser!
fn parse_expr<'a>(i: &'a str) -> IResult<&'a str, Expr, VerboseError<&'a str>> {
preceded(multispace0, alt((parse_constant, parse_application, parse_if, parse_quote)))(i)
preceded(
multispace0,
alt((parse_constant, parse_application, parse_if, parse_quote)),
)(i)
}
/// And that's it!
@ -276,7 +295,10 @@ fn eval_expression(e: Expr) -> Option<Expr> {
}
Expr::Application(head, tail) => {
let reduced_head = eval_expression(*head)?;
let reduced_tail = tail.into_iter().map(|expr| eval_expression(expr)).collect::<Option<Vec<Expr>>>()?;
let reduced_tail = tail
.into_iter()
.map(|expr| eval_expression(expr))
.collect::<Option<Vec<Expr>>>()?;
if let Expr::Constant(Atom::BuiltIn(bi)) = reduced_head {
Some(Expr::Constant(match bi {
BuiltIn::Plus => Atom::Num(
@ -295,7 +317,12 @@ fn eval_expression(e: Expr) -> Option<Expr> {
.into_iter()
.product(),
),
BuiltIn::Equal => Atom::Boolean(reduced_tail.iter().zip(reduced_tail.iter().skip(1)).all(|(a, b)| a == b)),
BuiltIn::Equal => Atom::Boolean(
reduced_tail
.iter()
.zip(reduced_tail.iter().skip(1))
.all(|(a, b)| a == b),
),
BuiltIn::Not => {
if reduced_tail.len() != 1 {
return None;
@ -349,5 +376,9 @@ fn main() {
*
/)
456 123)";
println!("\"{}\"\nevaled gives us: {:?}", expression_1, eval_from_str(expression_1));
println!(
"\"{}\"\nevaled gives us: {:?}",
expression_1,
eval_from_str(expression_1)
);
}

View File

@ -86,7 +86,9 @@ fn parse_escaped_char<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a
/// Parse a backslash, followed by any amount of whitespace. This is used later
/// to discard any escaped whitespace.
fn parse_escaped_whitespace<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, &'a str, E> {
fn parse_escaped_whitespace<'a, E: ParseError<&'a str>>(
input: &'a str,
) -> IResult<&'a str, &'a str, E> {
preceded(char('\\'), multispace1)(input)
}
@ -115,7 +117,9 @@ enum StringFragment<'a> {
/// Combine parse_literal, parse_escaped_whitespace, and parse_escaped_char
/// into a StringFragment.
fn parse_fragment<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, StringFragment<'a>, E> {
fn parse_fragment<'a, E: ParseError<&'a str>>(
input: &'a str,
) -> IResult<&'a str, StringFragment<'a>, E> {
alt((
// The `map` combinator runs a parser, then applies a function to the output
// of that parser.

View File

@ -1,3 +1,2 @@
tab_spaces = 2
struct_field_align_threshold = 100
max_width = 140
max_width = 100

View File

@ -3,11 +3,13 @@
use crate::error::{ErrorKind, ParseError};
use crate::internal::{Err, IResult};
use crate::lib::std::ops::{AddAssign, RangeFrom, Shl, Shr, Div};
use crate::lib::std::ops::{AddAssign, Div, RangeFrom, Shl, Shr};
use crate::traits::{InputIter, InputLength, Slice, ToUsize};
/// generates a parser taking `count` bits
pub fn take<I, O, C, E: ParseError<(I, usize)>>(count: C) -> impl Fn((I, usize)) -> IResult<(I, usize), O, E>
pub fn take<I, O, C, E: ParseError<(I, usize)>>(
count: C,
) -> impl Fn((I, usize)) -> IResult<(I, usize), O, E>
where
I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
C: ToUsize,
@ -20,11 +22,14 @@ where
} else {
let cnt = (count + bit_offset).div(8);
if input.input_len() * 8 < count + bit_offset {
Err(Err::Error(E::from_error_kind((input, bit_offset), ErrorKind::Eof)))
Err(Err::Error(E::from_error_kind(
(input, bit_offset),
ErrorKind::Eof,
)))
} else {
let mut acc:O = (0 as u8).into();
let mut offset: usize = bit_offset;
let mut remaining: usize = count;
let mut acc: O = (0 as u8).into();
let mut offset: usize = bit_offset;
let mut remaining: usize = count;
let mut end_offset: usize = 0;
for byte in input.iter_elements().take(cnt + 1) {
@ -47,14 +52,17 @@ where
offset = 0;
}
}
Ok(( (input.slice(cnt..), end_offset) , acc))
Ok(((input.slice(cnt..), end_offset), acc))
}
}
}
}
/// generates a parser taking `count` bits and comparing them to `pattern`
pub fn tag<I, O, C, E: ParseError<(I, usize)>>(pattern: O, count: C) -> impl Fn((I, usize)) -> IResult<(I, usize), O, E>
pub fn tag<I, O, C, E: ParseError<(I, usize)>>(
pattern: O,
count: C,
) -> impl Fn((I, usize)) -> IResult<(I, usize), O, E>
where
I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength + Clone,
C: ToUsize,

View File

@ -134,9 +134,9 @@ macro_rules! tag_bits (
#[cfg(test)]
mod tests {
use crate::lib::std::ops::{AddAssign, Shl, Shr};
use crate::internal::{Err, Needed, IResult};
use crate::error::ErrorKind;
use crate::internal::{Err, IResult, Needed};
use crate::lib::std::ops::{AddAssign, Shl, Shr};
#[test]
fn take_bits() {
@ -157,11 +157,8 @@ mod tests {
assert_eq!(take_bits!((sl, 6), 11u8), Ok(((&sl[2..], 1), 1504)));
assert_eq!(take_bits!((sl, 0), 20u8), Ok(((&sl[2..], 4), 700_163)));
assert_eq!(take_bits!((sl, 4), 20u8), Ok(((&sl[3..], 0), 716_851)));
let r: IResult<_,u32> = take_bits!((sl, 4), 22u8);
assert_eq!(
r,
Err(Err::Incomplete(Needed::new(22)))
);
let r: IResult<_, u32> = take_bits!((sl, 4), 22u8);
assert_eq!(r, Err(Err::Incomplete(Needed::new(22))));
}
#[test]
@ -203,11 +200,17 @@ mod tests {
);
}
named!(bits_bytes_bs, bits!(bytes!(crate::combinator::rest::<_, (&[u8], ErrorKind)>)));
named!(
bits_bytes_bs,
bits!(bytes!(crate::combinator::rest::<_, (&[u8], ErrorKind)>))
);
#[test]
fn bits_bytes() {
let input = [0b10_10_10_10];
assert_eq!(bits_bytes_bs(&input[..]), Ok((&[][..], &[0b10_10_10_10][..])));
assert_eq!(
bits_bytes_bs(&input[..]),
Ok((&[][..], &[0b10_10_10_10][..]))
);
}
#[derive(PartialEq, Debug)]
@ -255,9 +258,6 @@ mod tests {
Ok(((&sl[3..], 0), FakeUint(716_851)))
);
let r3: IResult<_, FakeUint> = take_bits!((sl, 4), 22u8);
assert_eq!(
r3,
Err(Err::Incomplete(Needed::new(22)))
);
assert_eq!(r3, Err(Err::Incomplete(Needed::new(22))));
}
}

View File

@ -4,14 +4,13 @@
#[macro_use]
mod macros;
pub mod streaming;
pub mod complete;
pub mod streaming;
use crate::error::{ParseError, ErrorKind};
use crate::error::{ErrorKind, ParseError};
use crate::internal::{Err, IResult, Needed};
use crate::lib::std::ops::RangeFrom;
use crate::traits::{Slice, ErrorConvert};
use crate::traits::{ErrorConvert, Slice};
/// Converts a byte-level input to a bit-level input, for consumption by a parser that uses bits.
///
@ -34,7 +33,9 @@ use crate::traits::{Slice, ErrorConvert};
///
/// assert_eq!(take_4_bits( sl ), Ok( (&sl[1..], 0xA) ));
/// ```
pub fn bits<I, O, E1: ParseError<(I, usize)>+ErrorConvert<E2>, E2: ParseError<I>, P>(parser: P) -> impl Fn(I) -> IResult<I, O, E2>
pub fn bits<I, O, E1: ParseError<(I, usize)> + ErrorConvert<E2>, E2: ParseError<I>, P>(
parser: P,
) -> impl Fn(I) -> IResult<I, O, E2>
where
I: Slice<RangeFrom<usize>>,
P: Fn((I, usize)) -> IResult<(I, usize), O, E1>,
@ -51,7 +52,10 @@ where
}
#[doc(hidden)]
pub fn bitsc<I, O, E1: ParseError<(I, usize)>+ErrorConvert<E2>, E2: ParseError<I>, P>(input: I, parser: P) -> IResult<I, O, E2>
pub fn bitsc<I, O, E1: ParseError<(I, usize)> + ErrorConvert<E2>, E2: ParseError<I>, P>(
input: I,
parser: P,
) -> IResult<I, O, E2>
where
I: Slice<RangeFrom<usize>>,
P: Fn((I, usize)) -> IResult<(I, usize), O, E1>,
@ -84,7 +88,9 @@ where
///
/// assert_eq!(parse( input ), Ok(( &[][..], (0xd, 0xea, &[0xbe, 0xaf][..]) )));
/// ```
pub fn bytes<I, O, E1: ParseError<I>+ErrorConvert<E2>, E2: ParseError<(I, usize)>, P>(parser: P) -> impl Fn((I, usize)) -> IResult<(I, usize), O, E2>
pub fn bytes<I, O, E1: ParseError<I> + ErrorConvert<E2>, E2: ParseError<(I, usize)>, P>(
parser: P,
) -> impl Fn((I, usize)) -> IResult<(I, usize), O, E2>
where
I: Slice<RangeFrom<usize>> + Clone,
P: Fn(I) -> IResult<I, O, E1>,
@ -110,7 +116,10 @@ where
}
#[doc(hidden)]
pub fn bytesc<I, O, E1: ParseError<I>+ErrorConvert<E2>, E2: ParseError<(I, usize)>, P>(input: (I, usize), parser: P) -> IResult<(I, usize), O, E2>
pub fn bytesc<I, O, E1: ParseError<I> + ErrorConvert<E2>, E2: ParseError<(I, usize)>, P>(
input: (I, usize),
parser: P,
) -> IResult<(I, usize), O, E2>
where
I: Slice<RangeFrom<usize>> + Clone,
P: Fn(I) -> IResult<I, O, E1>,

View File

@ -3,11 +3,13 @@
use crate::error::{ErrorKind, ParseError};
use crate::internal::{Err, IResult, Needed};
use crate::lib::std::ops::{AddAssign, RangeFrom, Shl, Shr, Div};
use crate::lib::std::ops::{AddAssign, Div, RangeFrom, Shl, Shr};
use crate::traits::{InputIter, InputLength, Slice, ToUsize};
/// generates a parser taking `count` bits
pub fn take<I, O, C, E: ParseError<(I, usize)>>(count: C) -> impl Fn((I, usize)) -> IResult<(I, usize), O, E>
pub fn take<I, O, C, E: ParseError<(I, usize)>>(
count: C,
) -> impl Fn((I, usize)) -> IResult<(I, usize), O, E>
where
I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
C: ToUsize,
@ -22,9 +24,9 @@ where
if input.input_len() * 8 < count + bit_offset {
Err(Err::Incomplete(Needed::new(count as usize)))
} else {
let mut acc:O = (0 as u8).into();
let mut offset: usize = bit_offset;
let mut remaining: usize = count;
let mut acc: O = (0 as u8).into();
let mut offset: usize = bit_offset;
let mut remaining: usize = count;
let mut end_offset: usize = 0;
for byte in input.iter_elements().take(cnt + 1) {
@ -47,14 +49,17 @@ where
offset = 0;
}
}
Ok(( (input.slice(cnt..), end_offset) , acc))
Ok(((input.slice(cnt..), end_offset), acc))
}
}
}
}
/// generates a parser taking `count` bits and comparing them to `pattern`
pub fn tag<I, O, C, E: ParseError<(I, usize)>>(pattern: O, count: C) -> impl Fn((I, usize)) -> IResult<(I, usize), O, E>
pub fn tag<I, O, C, E: ParseError<(I, usize)>>(
pattern: O,
count: C,
) -> impl Fn((I, usize)) -> IResult<(I, usize), O, E>
where
I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength + Clone,
C: ToUsize,

View File

@ -720,15 +720,15 @@ macro_rules! permutation_iterator (
#[cfg(test)]
mod tests {
use crate::error::ErrorKind;
use crate::internal::{Err, IResult, Needed};
#[cfg(feature = "alloc")]
use crate::{
error::ParseError,
lib::std::{
fmt::Debug,
string::{String, ToString}
}
string::{String, ToString},
},
};
use crate::internal::{Err, IResult, Needed};
// reproduce the tag and take macros, because of module import order
macro_rules! tag (
@ -810,7 +810,10 @@ mod tests {
}
fn append(input: I, kind: ErrorKind, other: Self) -> Self {
ErrorStr(format!("custom error message: ({:?}, {:?}) - {:?}", input, kind, other))
ErrorStr(format!(
"custom error message: ({:?}, {:?}) - {:?}",
input, kind, other
))
}
}
@ -854,7 +857,10 @@ mod tests {
assert_eq!(alt4(b), Ok((&b""[..], b)));
// test the alternative syntax
named!(alt5<bool>, alt!(tag!("abcd") => { |_| false } | tag!("efgh") => { |_| true }));
named!(
alt5<bool>,
alt!(tag!("abcd") => { |_| false } | tag!("efgh") => { |_| true })
);
assert_eq!(alt5(a), Ok((&b""[..], false)));
assert_eq!(alt5(b), Ok((&b""[..], true)));
@ -899,7 +905,13 @@ mod tests {
let b = &b"efghijkl"[..];
assert_eq!(sw(b), Ok((&b""[..], &b"ijkl"[..])));
let c = &b"afghijkl"[..];
assert_eq!(sw(c), Err(Err::Error(error_position!(&b"afghijkl"[..], ErrorKind::Switch))));
assert_eq!(
sw(c),
Err(Err::Error(error_position!(
&b"afghijkl"[..],
ErrorKind::Switch
)))
);
let a = &b"xxxxefgh"[..];
assert_eq!(sw(a), Ok((&b"gh"[..], &b"ef"[..])));
@ -907,7 +919,10 @@ mod tests {
#[test]
fn permutation() {
named!(perm<(&[u8], &[u8], &[u8])>, permutation!(tag!("abcd"), tag!("efg"), tag!("hi")));
named!(
perm<(&[u8], &[u8], &[u8])>,
permutation!(tag!("abcd"), tag!("efg"), tag!("hi"))
);
let expected = (&b"abcd"[..], &b"efg"[..], &b"hi"[..]);

View File

@ -42,7 +42,9 @@ pub trait Alt<I, O, E> {
///
/// with a custom error type, it is possible to have alt return the error of the parser
/// that went the farthest in the input data
pub fn alt<I: Clone, O, E: ParseError<I>, List: Alt<I, O, E>>(mut l: List) -> impl FnMut(I) -> IResult<I, O, E> {
pub fn alt<I: Clone, O, E: ParseError<I>, List: Alt<I, O, E>>(
mut l: List,
) -> impl FnMut(I) -> IResult<I, O, E> {
move |i: I| l.choice(i)
}
@ -80,7 +82,9 @@ pub trait Permutation<I, O, E> {
/// assert_eq!(parser("abc;"), Err(Err::Error(error_position!(";", ErrorKind::Permutation))));
/// # }
/// ```
pub fn permutation<I: Clone, O, E: ParseError<I>, List: Permutation<I, O, E>>(mut l: List) -> impl FnMut(I) -> IResult<I, O, E> {
pub fn permutation<I: Clone, O, E: ParseError<I>, List: Permutation<I, O, E>>(
mut l: List,
) -> impl FnMut(I) -> IResult<I, O, E> {
move |i: I| l.permutation(i)
}

View File

@ -5,7 +5,10 @@ use crate::error::ParseError;
use crate::internal::{Err, IResult, Parser};
use crate::lib::std::ops::RangeFrom;
use crate::lib::std::result::Result::*;
use crate::traits::{Compare, CompareResult, FindSubstring, FindToken, InputIter, InputLength, InputTake, InputTakeAtPosition, Slice, ToUsize};
use crate::traits::{
Compare, CompareResult, FindSubstring, FindToken, InputIter, InputLength, InputTake,
InputTakeAtPosition, Slice, ToUsize,
};
/// Recognizes a pattern
///
@ -27,7 +30,9 @@ use crate::traits::{Compare, CompareResult, FindSubstring, FindToken, InputIter,
/// assert_eq!(parser("Something"), Err(Err::Error(("Something", ErrorKind::Tag))));
/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
/// ```
pub fn tag<T, Input, Error: ParseError<Input>>(tag: T) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn tag<T, Input, Error: ParseError<Input>>(
tag: T,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
Input: InputTake + Compare<T>,
T: InputLength + Clone,
@ -68,7 +73,9 @@ where
/// assert_eq!(parser("Something"), Err(Err::Error(("Something", ErrorKind::Tag))));
/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
/// ```
pub fn tag_no_case<T, Input, Error: ParseError<Input>>(tag: T) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn tag_no_case<T, Input, Error: ParseError<Input>>(
tag: T,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
Input: InputTake + Compare<T>,
T: InputLength + Clone,
@ -110,7 +117,9 @@ where
/// assert_eq!(not_space("Nospace"), Ok(("", "Nospace")));
/// assert_eq!(not_space(""), Err(Err::Error(("", ErrorKind::IsNot))));
/// ```
pub fn is_not<T, Input, Error: ParseError<Input>>(arr: T) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn is_not<T, Input, Error: ParseError<Input>>(
arr: T,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
Input: InputTakeAtPosition,
T: FindToken<<Input as InputTakeAtPosition>::Item>,
@ -144,7 +153,9 @@ where
/// assert_eq!(hex("D15EA5E"), Ok(("", "D15EA5E")));
/// assert_eq!(hex(""), Err(Err::Error(("", ErrorKind::IsA))));
/// ```
pub fn is_a<T, Input, Error: ParseError<Input>>(arr: T) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn is_a<T, Input, Error: ParseError<Input>>(
arr: T,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
Input: InputTakeAtPosition,
T: FindToken<<Input as InputTakeAtPosition>::Item>,
@ -176,7 +187,9 @@ where
/// assert_eq!(alpha(b"latin"), Ok((&b""[..], &b"latin"[..])));
/// assert_eq!(alpha(b""), Ok((&b""[..], &b""[..])));
/// ```
pub fn take_while<F, Input, Error: ParseError<Input>>(cond: F) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn take_while<F, Input, Error: ParseError<Input>>(
cond: F,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
Input: InputTakeAtPosition,
F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
@ -206,7 +219,9 @@ where
/// assert_eq!(alpha(b"latin"), Ok((&b""[..], &b"latin"[..])));
/// assert_eq!(alpha(b"12345"), Err(Err::Error((&b"12345"[..], ErrorKind::TakeWhile1))));
/// ```
pub fn take_while1<F, Input, Error: ParseError<Input>>(cond: F) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn take_while1<F, Input, Error: ParseError<Input>>(
cond: F,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
Input: InputTakeAtPosition,
F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
@ -242,7 +257,11 @@ where
/// assert_eq!(short_alpha(b"ed"), Err(Err::Error((&b"ed"[..], ErrorKind::TakeWhileMN))));
/// assert_eq!(short_alpha(b"12345"), Err(Err::Error((&b"12345"[..], ErrorKind::TakeWhileMN))));
/// ```
pub fn take_while_m_n<F, Input, Error: ParseError<Input>>(m: usize, n: usize, cond: F) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn take_while_m_n<F, Input, Error: ParseError<Input>>(
m: usize,
n: usize,
cond: F,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
Input: InputTake + InputIter + InputLength + Slice<RangeFrom<usize>>,
F: Fn(<Input as InputIter>::Item) -> bool,
@ -257,14 +276,20 @@ where
let res: IResult<_, _, Error> = if let Some(index) = input.slice_index(idx) {
Ok(input.take_split(index))
} else {
Err(Err::Error(Error::from_error_kind(input, ErrorKind::TakeWhileMN)))
Err(Err::Error(Error::from_error_kind(
input,
ErrorKind::TakeWhileMN,
)))
};
res
} else {
let res: IResult<_, _, Error> = if let Some(index) = input.slice_index(n) {
Ok(input.take_split(index))
} else {
Err(Err::Error(Error::from_error_kind(input, ErrorKind::TakeWhileMN)))
Err(Err::Error(Error::from_error_kind(
input,
ErrorKind::TakeWhileMN,
)))
};
res
}
@ -278,7 +303,10 @@ where
if len >= n {
match input.slice_index(n) {
Some(index) => Ok(input.take_split(index)),
None => Err(Err::Error(Error::from_error_kind(input, ErrorKind::TakeWhileMN)))
None => Err(Err::Error(Error::from_error_kind(
input,
ErrorKind::TakeWhileMN,
))),
}
} else {
if len >= m && len <= n {
@ -314,7 +342,9 @@ where
/// assert_eq!(till_colon("12345"), Ok(("", "12345")));
/// assert_eq!(till_colon(""), Ok(("", "")));
/// ```
pub fn take_till<F, Input, Error: ParseError<Input>>(cond: F) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn take_till<F, Input, Error: ParseError<Input>>(
cond: F,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
Input: InputTakeAtPosition,
F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
@ -345,7 +375,9 @@ where
/// assert_eq!(till_colon("12345"), Ok(("", "12345")));
/// assert_eq!(till_colon(""), Err(Err::Error(("", ErrorKind::TakeTill1))));
/// ```
pub fn take_till1<F, Input, Error: ParseError<Input>>(cond: F) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn take_till1<F, Input, Error: ParseError<Input>>(
cond: F,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
Input: InputTakeAtPosition,
F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
@ -375,7 +407,9 @@ where
/// assert_eq!(take6("short"), Err(Err::Error(("short", ErrorKind::Eof))));
/// assert_eq!(take6(""), Err(Err::Error(("", ErrorKind::Eof))));
/// ```
pub fn take<C, Input, Error: ParseError<Input>>(count: C) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn take<C, Input, Error: ParseError<Input>>(
count: C,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
Input: InputIter + InputTake,
C: ToUsize,
@ -406,7 +440,9 @@ where
/// assert_eq!(until_eof("hello, world"), Err(Err::Error(("hello, world", ErrorKind::TakeUntil))));
/// assert_eq!(until_eof(""), Err(Err::Error(("", ErrorKind::TakeUntil))));
/// ```
pub fn take_until<T, Input, Error: ParseError<Input>>(tag: T) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn take_until<T, Input, Error: ParseError<Input>>(
tag: T,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
Input: InputTake + FindSubstring<T>,
T: InputLength + Clone,
@ -443,9 +479,19 @@ where
/// assert_eq!(esc(r#"12\"34;"#), Ok((";", r#"12\"34"#)));
/// ```
///
pub fn escaped<'a, Input:'a, Error, F, G, O1, O2>(mut normal: F, control_char: char, mut escapable: G) -> impl FnMut(Input) -> IResult<Input, Input, Error>
pub fn escaped<'a, Input: 'a, Error, F, G, O1, O2>(
mut normal: F,
control_char: char,
mut escapable: G,
) -> impl FnMut(Input) -> IResult<Input, Input, Error>
where
Input: Clone + crate::traits::Offset + InputLength + InputTake + InputTakeAtPosition + Slice<RangeFrom<usize>> + InputIter,
Input: Clone
+ crate::traits::Offset
+ InputLength
+ InputTake
+ InputTakeAtPosition
+ Slice<RangeFrom<usize>>
+ InputIter,
<Input as InputIter>::Item: crate::traits::AsChar,
F: Parser<Input, O1, Error>,
G: Parser<Input, O2, Error>,
@ -470,7 +516,10 @@ where
if i.iter_elements().next().unwrap().as_char() == control_char {
let next = control_char.len_utf8();
if next >= i.input_len() {
return Err(Err::Error(Error::from_error_kind(input, ErrorKind::Escaped)));
return Err(Err::Error(Error::from_error_kind(
input,
ErrorKind::Escaped,
)));
} else {
match escapable.parse(i.slice(next..)) {
Ok((i2, _)) => {
@ -486,7 +535,10 @@ where
} else {
let index = input.offset(&i);
if index == 0 {
return Err(Err::Error(Error::from_error_kind(input, ErrorKind::Escaped)));
return Err(Err::Error(Error::from_error_kind(
input,
ErrorKind::Escaped,
)));
}
return Ok(input.take_split(index));
}
@ -502,9 +554,20 @@ where
}
#[doc(hidden)]
pub fn escapedc<Input, Error, F, G, O1, O2>(i: Input, normal: F, control_char: char, escapable: G) -> IResult<Input, Input, Error>
pub fn escapedc<Input, Error, F, G, O1, O2>(
i: Input,
normal: F,
control_char: char,
escapable: G,
) -> IResult<Input, Input, Error>
where
Input: Clone + crate::traits::Offset + InputLength + InputTake + InputTakeAtPosition + Slice<RangeFrom<usize>> + InputIter,
Input: Clone
+ crate::traits::Offset
+ InputLength
+ InputTake
+ InputTakeAtPosition
+ Slice<RangeFrom<usize>>
+ InputIter,
<Input as InputIter>::Item: crate::traits::AsChar,
F: Fn(Input) -> IResult<Input, O1, Error>,
G: Fn(Input) -> IResult<Input, O2, Error>,
@ -551,7 +614,13 @@ pub fn escaped_transform<Input, Error, F, G, O1, O2, ExtendItem, Output>(
mut transform: G,
) -> impl FnMut(Input) -> IResult<Input, Output, Error>
where
Input: Clone + crate::traits::Offset + InputLength + InputTake + InputTakeAtPosition + Slice<RangeFrom<usize>> + InputIter,
Input: Clone
+ crate::traits::Offset
+ InputLength
+ InputTake
+ InputTakeAtPosition
+ Slice<RangeFrom<usize>>
+ InputIter,
Input: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
O1: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
O2: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
@ -589,7 +658,10 @@ where
let input_len = input.input_len();
if next >= input_len {
return Err(Err::Error(Error::from_error_kind(remainder, ErrorKind::EscapedTransform)));
return Err(Err::Error(Error::from_error_kind(
remainder,
ErrorKind::EscapedTransform,
)));
} else {
match transform.parse(i.slice(next..)) {
Ok((i2, o)) => {
@ -605,7 +677,10 @@ where
}
} else {
if index == 0 {
return Err(Err::Error(Error::from_error_kind(remainder, ErrorKind::EscapedTransform)));
return Err(Err::Error(Error::from_error_kind(
remainder,
ErrorKind::EscapedTransform,
)));
}
return Ok((remainder, res));
}
@ -626,7 +701,13 @@ pub fn escaped_transformc<Input, Error, F, G, O1, O2, ExtendItem, Output>(
transform: G,
) -> IResult<Input, Output, Error>
where
Input: Clone + crate::traits::Offset + InputLength + InputTake + InputTakeAtPosition + Slice<RangeFrom<usize>> + InputIter,
Input: Clone
+ crate::traits::Offset
+ InputLength
+ InputTake
+ InputTakeAtPosition
+ Slice<RangeFrom<usize>>
+ InputIter,
Input: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
O1: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
O2: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
@ -639,7 +720,6 @@ where
Error: ParseError<Input>,
{
escaped_transform(normal, control_char, transform)(i)
}
#[cfg(test)]
@ -648,13 +728,15 @@ mod tests {
#[test]
fn complete_take_while_m_n_utf8_all_matching() {
let result: IResult<&str, &str> = super::take_while_m_n(1, 4, |c: char| c.is_alphabetic())("øn");
let result: IResult<&str, &str> =
super::take_while_m_n(1, 4, |c: char| c.is_alphabetic())("øn");
assert_eq!(result, Ok(("", "øn")));
}
#[test]
fn complete_take_while_m_n_utf8_all_matching_substring() {
let result: IResult<&str, &str> = super::take_while_m_n(1, 1, |c: char| c.is_alphabetic())("øn");
let result: IResult<&str, &str> =
super::take_while_m_n(1, 1, |c: char| c.is_alphabetic())("øn");
assert_eq!(result, Ok(("n", "ø")));
}
}

View File

@ -449,14 +449,17 @@ macro_rules! take_until1 (
#[cfg(test)]
mod tests {
use crate::internal::{Err, Needed, IResult};
use crate::character::is_alphabetic;
use crate::character::streaming::{
alpha1 as alpha, alphanumeric1 as alphanumeric, digit1 as digit, hex_digit1 as hex_digit,
multispace1 as multispace, oct_digit1 as oct_digit, space1 as space,
};
use crate::error::ErrorKind;
use crate::internal::{Err, IResult, Needed};
#[cfg(feature = "alloc")]
use crate::lib::std::string::String;
#[cfg(feature = "alloc")]
use crate::lib::std::vec::Vec;
use crate::character::streaming::{alpha1 as alpha, alphanumeric1 as alphanumeric, digit1 as digit, hex_digit1 as hex_digit, multispace1 as multispace, oct_digit1 as oct_digit, space1 as space};
use crate::error::ErrorKind;
use crate::character::is_alphabetic;
#[cfg(feature = "alloc")]
macro_rules! one_of (
@ -491,7 +494,10 @@ mod tests {
assert_eq!(a_or_b(b), Ok((&b"cde"[..], &b"b"[..])));
let c = &b"cdef"[..];
assert_eq!(a_or_b(c), Err(Err::Error(error_position!(c, ErrorKind::IsA))));
assert_eq!(
a_or_b(c),
Err(Err::Error(error_position!(c, ErrorKind::IsA)))
);
let d = &b"bacdef"[..];
assert_eq!(a_or_b(d), Ok((&b"cdef"[..], &b"ba"[..])));
@ -508,7 +514,10 @@ mod tests {
assert_eq!(a_or_b(b), Ok((&b"bde"[..], &b"c"[..])));
let c = &b"abab"[..];
assert_eq!(a_or_b(c), Err(Err::Error(error_position!(c, ErrorKind::IsNot))));
assert_eq!(
a_or_b(c),
Err(Err::Error(error_position!(c, ErrorKind::IsNot)))
);
let d = &b"cdefba"[..];
assert_eq!(a_or_b(d), Ok((&b"ba"[..], &b"cdef"[..])));
@ -527,7 +536,13 @@ mod tests {
assert_eq!(esc(&b"\\\"abcd;"[..]), Ok((&b";"[..], &b"\\\"abcd"[..])));
assert_eq!(esc(&b"\\n;"[..]), Ok((&b";"[..], &b"\\n"[..])));
assert_eq!(esc(&b"ab\\\"12"[..]), Ok((&b"12"[..], &b"ab\\\""[..])));
assert_eq!(esc(&b"AB\\"[..]), Err(Err::Error(error_position!(&b"AB\\"[..], ErrorKind::Escaped))));
assert_eq!(
esc(&b"AB\\"[..]),
Err(Err::Error(error_position!(
&b"AB\\"[..],
ErrorKind::Escaped
)))
);
assert_eq!(
esc(&b"AB\\A"[..]),
Err(Err::Error(error_node_position!(
@ -550,7 +565,10 @@ mod tests {
assert_eq!(esc("\\\"abcd;"), Ok((";", "\\\"abcd")));
assert_eq!(esc("\\n;"), Ok((";", "\\n")));
assert_eq!(esc("ab\\\"12"), Ok(("12", "ab\\\"")));
assert_eq!(esc("AB\\"), Err(Err::Error(error_position!("AB\\", ErrorKind::Escaped))));
assert_eq!(
esc("AB\\"),
Err(Err::Error(error_position!("AB\\", ErrorKind::Escaped)))
);
assert_eq!(
esc("AB\\A"),
Err(Err::Error(error_node_position!(
@ -594,11 +612,26 @@ mod tests {
);
assert_eq!(esc(&b"abcd;"[..]), Ok((&b";"[..], String::from("abcd"))));
assert_eq!(esc(&b"ab\\\"cd;"[..]), Ok((&b";"[..], String::from("ab\"cd"))));
assert_eq!(esc(&b"\\\"abcd;"[..]), Ok((&b";"[..], String::from("\"abcd"))));
assert_eq!(
esc(&b"ab\\\"cd;"[..]),
Ok((&b";"[..], String::from("ab\"cd")))
);
assert_eq!(
esc(&b"\\\"abcd;"[..]),
Ok((&b";"[..], String::from("\"abcd")))
);
assert_eq!(esc(&b"\\n;"[..]), Ok((&b";"[..], String::from("\n"))));
assert_eq!(esc(&b"ab\\\"12"[..]), Ok((&b"12"[..], String::from("ab\""))));
assert_eq!(esc(&b"AB\\"[..]), Err(Err::Error(error_position!(&b"\\"[..], ErrorKind::EscapedTransform))));
assert_eq!(
esc(&b"ab\\\"12"[..]),
Ok((&b"12"[..], String::from("ab\"")))
);
assert_eq!(
esc(&b"AB\\"[..]),
Err(Err::Error(error_position!(
&b"\\"[..],
ErrorKind::EscapedTransform
)))
);
assert_eq!(
esc(&b"AB\\A"[..]),
Err(Err::Error(error_node_position!(
@ -622,8 +655,14 @@ mod tests {
to_s
)
);
assert_eq!(esc2(&b"ab&egrave;DEF;"[..]), Ok((&b";"[..], String::from("abèDEF"))));
assert_eq!(esc2(&b"ab&egrave;D&agrave;EF;"[..]), Ok((&b";"[..], String::from("abèDàEF"))));
assert_eq!(
esc2(&b"ab&egrave;DEF;"[..]),
Ok((&b";"[..], String::from("abèDEF")))
);
assert_eq!(
esc2(&b"ab&egrave;D&agrave;EF;"[..]),
Ok((&b";"[..], String::from("abèDàEF")))
);
}
#[cfg(feature = "std")]
@ -642,7 +681,13 @@ mod tests {
assert_eq!(esc("\\\"abcd;"), Ok((";", String::from("\"abcd"))));
assert_eq!(esc("\\n;"), Ok((";", String::from("\n"))));
assert_eq!(esc("ab\\\"12"), Ok(("12", String::from("ab\""))));
assert_eq!(esc("AB\\"), Err(Err::Error(error_position!("\\", ErrorKind::EscapedTransform))));
assert_eq!(
esc("AB\\"),
Err(Err::Error(error_position!(
"\\",
ErrorKind::EscapedTransform
)))
);
assert_eq!(
esc("AB\\A"),
Err(Err::Error(error_node_position!(
@ -659,7 +704,10 @@ mod tests {
))
);
assert_eq!(esc2("ab&egrave;DEF;"), Ok((";", String::from("abèDEF"))));
assert_eq!(esc2("ab&egrave;D&agrave;EF;"), Ok((";", String::from("abèDàEF"))));
assert_eq!(
esc2("ab&egrave;D&agrave;EF;"),
Ok((";", String::from("abèDàEF")))
);
named!(esc3<&str, String>, escaped_transform!(alpha, '␛',
alt!(
@ -672,10 +720,10 @@ mod tests {
fn take_str_test() {
let a = b"omnomnom";
let res: IResult<_,_,(&[u8], ErrorKind)> = take_str!(&a[..], 5u32);
let res: IResult<_, _, (&[u8], ErrorKind)> = take_str!(&a[..], 5u32);
assert_eq!(res, Ok((&b"nom"[..], "omnom")));
let res: IResult<_,_,(&[u8], ErrorKind)> = take_str!(&a[..], 9u32);
let res: IResult<_, _, (&[u8], ErrorKind)> = take_str!(&a[..], 9u32);
assert_eq!(res, Err(Err::Incomplete(Needed::new(9))));
}
@ -695,7 +743,10 @@ mod tests {
#[test]
fn recognize() {
named!(x, recognize!(delimited!(tag!("<!--"), take!(5usize), tag!("-->"))));
named!(
x,
recognize!(delimited!(tag!("<!--"), take!(5usize), tag!("-->")))
);
let r = x(&b"<!-- abc --> aaa"[..]);
assert_eq!(r, Ok((&b" aaa"[..], &b"<!-- abc -->"[..])));
@ -755,7 +806,10 @@ mod tests {
assert_eq!(f(&a[..]), Err(Err::Incomplete(Needed::new(1))));
assert_eq!(f(&b[..]), Err(Err::Incomplete(Needed::new(1))));
assert_eq!(f(&c[..]), Ok((&b"123"[..], &b[..])));
assert_eq!(f(&d[..]), Err(Err::Error(error_position!(&d[..], ErrorKind::TakeWhile1))));
assert_eq!(
f(&d[..]),
Err(Err::Error(error_position!(&d[..], ErrorKind::TakeWhile1)))
);
}
#[test]
@ -773,12 +827,14 @@ mod tests {
assert_eq!(x(&c[..]), Err(Err::Incomplete(Needed::new(1))));
assert_eq!(x(&d[..]), Ok((&b"123"[..], &c[..])));
assert_eq!(x(&e[..]), Ok((&b"e"[..], &b"abcd"[..])));
assert_eq!(x(&f[..]), Err(Err::Error(error_position!(&f[..], ErrorKind::TakeWhileMN))));
assert_eq!(
x(&f[..]),
Err(Err::Error(error_position!(&f[..], ErrorKind::TakeWhileMN)))
);
}
#[test]
fn take_till() {
named!(f, take_till!(is_alphabetic));
let a = b"";
let b = b"abcd";
@ -793,7 +849,6 @@ mod tests {
#[test]
fn take_till1() {
named!(f, take_till1!(is_alphabetic));
let a = b"";
let b = b"abcd";
@ -801,7 +856,10 @@ mod tests {
let d = b"123";
assert_eq!(f(&a[..]), Err(Err::Incomplete(Needed::new(1))));
assert_eq!(f(&b[..]), Err(Err::Error(error_position!(&b[..], ErrorKind::TakeTill1))));
assert_eq!(
f(&b[..]),
Err(Err::Error(error_position!(&b[..], ErrorKind::TakeTill1)))
);
assert_eq!(f(&c[..]), Ok((&b"abcd"[..], &b"123"[..])));
assert_eq!(f(&d[..]), Err(Err::Incomplete(Needed::new(1))));
}
@ -875,7 +933,6 @@ mod tests {
#[cfg(nightly)]
#[bench]
fn take_while_bench(b: &mut Bencher) {
named!(f, take_while!(is_alphabetic));
b.iter(|| f(&b"abcdefghijklABCDEejfrfrjgro12aa"[..]));
}
@ -915,16 +972,28 @@ mod tests {
assert_eq!(test(&b"abcdefgh"[..]), Ok((&b"efgh"[..], &b"abcd"[..])));
assert_eq!(test(&b"ABCDefgh"[..]), Ok((&b"efgh"[..], &b"ABCD"[..])));
assert_eq!(test(&b"ab"[..]), Err(Err::Incomplete(Needed::new(4))));
assert_eq!(test(&b"Hello"[..]), Err(Err::Error(error_position!(&b"Hello"[..], ErrorKind::Tag))));
assert_eq!(test(&b"Hel"[..]), Err(Err::Error(error_position!(&b"Hel"[..], ErrorKind::Tag))));
assert_eq!(
test(&b"Hello"[..]),
Err(Err::Error(error_position!(&b"Hello"[..], ErrorKind::Tag)))
);
assert_eq!(
test(&b"Hel"[..]),
Err(Err::Error(error_position!(&b"Hel"[..], ErrorKind::Tag)))
);
named!(test2<&str, &str>, tag_no_case!("ABcd"));
assert_eq!(test2("aBCdefgh"), Ok(("efgh", "aBCd")));
assert_eq!(test2("abcdefgh"), Ok(("efgh", "abcd")));
assert_eq!(test2("ABCDefgh"), Ok(("efgh", "ABCD")));
assert_eq!(test2("ab"), Err(Err::Incomplete(Needed::new(4))));
assert_eq!(test2("Hello"), Err(Err::Error(error_position!(&"Hello"[..], ErrorKind::Tag))));
assert_eq!(test2("Hel"), Err(Err::Error(error_position!(&"Hel"[..], ErrorKind::Tag))));
assert_eq!(
test2("Hello"),
Err(Err::Error(error_position!(&"Hello"[..], ErrorKind::Tag)))
);
assert_eq!(
test2("Hel"),
Err(Err::Error(error_position!(&"Hel"[..], ErrorKind::Tag)))
);
}
#[test]

View File

@ -2,6 +2,5 @@
#[macro_use]
mod macros;
pub mod streaming;
pub mod complete;
pub mod streaming;

View File

@ -5,7 +5,10 @@ use crate::error::ParseError;
use crate::internal::{Err, IResult, Needed, Parser};
use crate::lib::std::ops::RangeFrom;
use crate::lib::std::result::Result::*;
use crate::traits::{Compare, CompareResult, FindSubstring, FindToken, InputIter, InputLength, InputTake, InputTakeAtPosition, Slice, ToUsize};
use crate::traits::{
Compare, CompareResult, FindSubstring, FindToken, InputIter, InputLength, InputTake,
InputTakeAtPosition, Slice, ToUsize,
};
/// Recognizes a pattern
///
@ -25,7 +28,9 @@ use crate::traits::{Compare, CompareResult, FindSubstring, FindToken, InputIter,
/// assert_eq!(parser("Something"), Err(Err::Error(("Something", ErrorKind::Tag))));
/// assert_eq!(parser(""), Err(Err::Incomplete(Needed::new(5))));
/// ```
pub fn tag<T, Input, Error: ParseError<Input>>(tag: T) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn tag<T, Input, Error: ParseError<Input>>(
tag: T,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
Input: InputTake + Compare<T>,
T: InputLength + Clone,
@ -66,7 +71,9 @@ where
/// assert_eq!(parser("Something"), Err(Err::Error(("Something", ErrorKind::Tag))));
/// assert_eq!(parser(""), Err(Err::Incomplete(Needed::new(5))));
/// ```
pub fn tag_no_case<T, Input, Error: ParseError<Input>>(tag: T) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn tag_no_case<T, Input, Error: ParseError<Input>>(
tag: T,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
Input: InputTake + Compare<T>,
T: InputLength + Clone,
@ -109,7 +116,9 @@ where
/// assert_eq!(not_space("Nospace"), Err(Err::Incomplete(Needed::new(1))));
/// assert_eq!(not_space(""), Err(Err::Incomplete(Needed::new(1))));
/// ```
pub fn is_not<T, Input, Error: ParseError<Input>>(arr: T) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn is_not<T, Input, Error: ParseError<Input>>(
arr: T,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
Input: InputTakeAtPosition,
T: FindToken<<Input as InputTakeAtPosition>::Item>,
@ -144,7 +153,9 @@ where
/// assert_eq!(hex("D15EA5E"), Err(Err::Incomplete(Needed::new(1))));
/// assert_eq!(hex(""), Err(Err::Incomplete(Needed::new(1))));
/// ```
pub fn is_a<T, Input, Error: ParseError<Input>>(arr: T) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn is_a<T, Input, Error: ParseError<Input>>(
arr: T,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
Input: InputTakeAtPosition,
T: FindToken<<Input as InputTakeAtPosition>::Item>,
@ -178,7 +189,9 @@ where
/// assert_eq!(alpha(b"latin"), Err(Err::Incomplete(Needed::new(1))));
/// assert_eq!(alpha(b""), Err(Err::Incomplete(Needed::new(1))));
/// ```
pub fn take_while<F, Input, Error: ParseError<Input>>(cond: F) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn take_while<F, Input, Error: ParseError<Input>>(
cond: F,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
Input: InputTakeAtPosition,
F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
@ -211,7 +224,9 @@ where
/// assert_eq!(alpha(b"latin"), Err(Err::Incomplete(Needed::new(1))));
/// assert_eq!(alpha(b"12345"), Err(Err::Error((&b"12345"[..], ErrorKind::TakeWhile1))));
/// ```
pub fn take_while1<F, Input, Error: ParseError<Input>>(cond: F) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn take_while1<F, Input, Error: ParseError<Input>>(
cond: F,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
Input: InputTakeAtPosition,
F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
@ -248,7 +263,11 @@ where
/// assert_eq!(short_alpha(b"ed"), Err(Err::Incomplete(Needed::new(1))));
/// assert_eq!(short_alpha(b"12345"), Err(Err::Error((&b"12345"[..], ErrorKind::TakeWhileMN))));
/// ```
pub fn take_while_m_n<F, Input, Error: ParseError<Input>>(m: usize, n: usize, cond: F) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn take_while_m_n<F, Input, Error: ParseError<Input>>(
m: usize,
n: usize,
cond: F,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
Input: InputTake + InputIter + InputLength,
F: Fn(<Input as InputIter>::Item) -> bool,
@ -263,14 +282,20 @@ where
let res: IResult<_, _, Error> = if let Some(index) = input.slice_index(idx) {
Ok(input.take_split(index))
} else {
Err(Err::Error(Error::from_error_kind(input, ErrorKind::TakeWhileMN)))
Err(Err::Error(Error::from_error_kind(
input,
ErrorKind::TakeWhileMN,
)))
};
res
} else {
let res: IResult<_, _, Error> = if let Some(index) = input.slice_index(n) {
Ok(input.take_split(index))
} else {
Err(Err::Error(Error::from_error_kind(input, ErrorKind::TakeWhileMN)))
Err(Err::Error(Error::from_error_kind(
input,
ErrorKind::TakeWhileMN,
)))
};
res
}
@ -284,7 +309,10 @@ where
if len >= n {
match input.slice_index(n) {
Some(index) => Ok(input.take_split(index)),
None => Err(Err::Error(Error::from_error_kind(input, ErrorKind::TakeWhileMN)))
None => Err(Err::Error(Error::from_error_kind(
input,
ErrorKind::TakeWhileMN,
))),
}
} else {
let needed = if m > len { m - len } else { 1 };
@ -319,7 +347,9 @@ where
/// assert_eq!(till_colon("12345"), Err(Err::Incomplete(Needed::new(1))));
/// assert_eq!(till_colon(""), Err(Err::Incomplete(Needed::new(1))));
/// ```
pub fn take_till<F, Input, Error: ParseError<Input>>(cond: F) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn take_till<F, Input, Error: ParseError<Input>>(
cond: F,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
Input: InputTakeAtPosition,
F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
@ -350,7 +380,9 @@ where
/// assert_eq!(till_colon("12345"), Err(Err::Incomplete(Needed::new(1))));
/// assert_eq!(till_colon(""), Err(Err::Incomplete(Needed::new(1))));
/// ```
pub fn take_till1<F, Input, Error: ParseError<Input>>(cond: F) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn take_till1<F, Input, Error: ParseError<Input>>(
cond: F,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
Input: InputTakeAtPosition,
F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
@ -381,7 +413,9 @@ where
/// assert_eq!(take6("short"), Err(Err::Incomplete(Needed::new(6)))); //N doesn't change
/// assert_eq!(take6(""), Err(Err::Incomplete(Needed::new(6))));
/// ```
pub fn take<C, Input, Error: ParseError<Input>>(count: C) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn take<C, Input, Error: ParseError<Input>>(
count: C,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
Input: InputIter + InputTake,
C: ToUsize,
@ -414,7 +448,9 @@ where
/// assert_eq!(until_eof("hello, world"), Err(Err::Incomplete(Needed::new(3))));
/// assert_eq!(until_eof(""), Err(Err::Incomplete(Needed::new(3))));
/// ```
pub fn take_until<T, Input, Error: ParseError<Input>>(tag: T) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn take_until<T, Input, Error: ParseError<Input>>(
tag: T,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
Input: InputTake + FindSubstring<T>,
T: InputLength + Clone,
@ -453,9 +489,19 @@ where
/// assert_eq!(esc("12\\\"34;"), Ok((";", "12\\\"34")));
/// ```
///
pub fn escaped<Input, Error, F, G, O1, O2>(mut normal: F, control_char: char, mut escapable: G) -> impl FnMut(Input) -> IResult<Input, Input, Error>
pub fn escaped<Input, Error, F, G, O1, O2>(
mut normal: F,
control_char: char,
mut escapable: G,
) -> impl FnMut(Input) -> IResult<Input, Input, Error>
where
Input: Clone + crate::traits::Offset + InputLength + InputTake + InputTakeAtPosition + Slice<RangeFrom<usize>> + InputIter,
Input: Clone
+ crate::traits::Offset
+ InputLength
+ InputTake
+ InputTakeAtPosition
+ Slice<RangeFrom<usize>>
+ InputIter,
<Input as InputIter>::Item: crate::traits::AsChar,
F: Parser<Input, O1, Error>,
G: Parser<Input, O2, Error>,
@ -509,9 +555,20 @@ where
}
#[doc(hidden)]
pub fn escapedc<Input, Error, F, G, O1, O2>(i: Input, normal: F, control_char: char, escapable: G) -> IResult<Input, Input, Error>
pub fn escapedc<Input, Error, F, G, O1, O2>(
i: Input,
normal: F,
control_char: char,
escapable: G,
) -> IResult<Input, Input, Error>
where
Input: Clone + crate::traits::Offset + InputLength + InputTake + InputTakeAtPosition + Slice<RangeFrom<usize>> + InputIter,
Input: Clone
+ crate::traits::Offset
+ InputLength
+ InputTake
+ InputTakeAtPosition
+ Slice<RangeFrom<usize>>
+ InputIter,
<Input as InputIter>::Item: crate::traits::AsChar,
F: Fn(Input) -> IResult<Input, O1, Error>,
G: Fn(Input) -> IResult<Input, O2, Error>,
@ -558,7 +615,13 @@ pub fn escaped_transform<Input, Error, F, G, O1, O2, ExtendItem, Output>(
mut transform: G,
) -> impl FnMut(Input) -> IResult<Input, Output, Error>
where
Input: Clone + crate::traits::Offset + InputLength + InputTake + InputTakeAtPosition + Slice<RangeFrom<usize>> + InputIter,
Input: Clone
+ crate::traits::Offset
+ InputLength
+ InputTake
+ InputTakeAtPosition
+ Slice<RangeFrom<usize>>
+ InputIter,
Input: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
O1: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
O2: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
@ -630,7 +693,13 @@ pub fn escaped_transformc<Input, Error, F, G, O1, O2, ExtendItem, Output>(
transform: G,
) -> IResult<Input, Output, Error>
where
Input: Clone + crate::traits::Offset + InputLength + InputTake + InputTakeAtPosition + Slice<RangeFrom<usize>> + InputIter,
Input: Clone
+ crate::traits::Offset
+ InputLength
+ InputTake
+ InputTakeAtPosition
+ Slice<RangeFrom<usize>>
+ InputIter,
Input: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
O1: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
O2: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
@ -643,5 +712,4 @@ where
Error: ParseError<Input>,
{
escaped_transform(normal, control_char, transform)(i)
}

View File

@ -2,12 +2,12 @@
//!
//! Functions recognizing specific characters.
use crate::internal::{Err, IResult};
use crate::error::ErrorKind;
use crate::error::ParseError;
use crate::internal::{Err, IResult};
use crate::lib::std::ops::{Range, RangeFrom, RangeTo};
use crate::traits::{AsChar, FindToken, InputIter, InputLength, InputTakeAtPosition, Slice};
use crate::traits::{Compare, CompareResult};
use crate::error::ErrorKind;
/// Recognizes one character.
///
@ -159,9 +159,7 @@ where
let c = item.as_char();
c == '\r' || c == '\n'
}) {
None => {
Ok((input.slice(input.input_len()..), input))
}
None => Ok((input.slice(input.input_len()..), input)),
Some(index) => {
let mut it = input.slice(index..).iter_elements();
let nth = it.next().unwrap().as_char();
@ -729,7 +727,6 @@ mod tests {
};
);
#[test]
fn character() {
let empty: &[u8] = b"";
@ -741,50 +738,35 @@ mod tests {
let f: &[u8] = b" ;";
//assert_eq!(alpha1::<_, (_, ErrorKind)>(a), Err(Err::Incomplete(Needed::Size(1))));
assert_parse!(alpha1(a), Ok((empty, a)));
assert_eq!(
alpha1(b),
Err(Err::Error((b, ErrorKind::Alpha)))
);
assert_eq!(alpha1(b), Err(Err::Error((b, ErrorKind::Alpha))));
assert_eq!(alpha1::<_, (_, ErrorKind)>(c), Ok((&c[1..], &b"a"[..])));
assert_eq!(alpha1::<_, (_, ErrorKind)>(d), Ok(("é12".as_bytes(), &b"az"[..])));
assert_eq!(
digit1(a),
Err(Err::Error((a, ErrorKind::Digit)))
alpha1::<_, (_, ErrorKind)>(d),
Ok(("é12".as_bytes(), &b"az"[..]))
);
assert_eq!(digit1(a), Err(Err::Error((a, ErrorKind::Digit))));
assert_eq!(digit1::<_, (_, ErrorKind)>(b), Ok((empty, b)));
assert_eq!(
digit1(c),
Err(Err::Error((c, ErrorKind::Digit)))
);
assert_eq!(
digit1(d),
Err(Err::Error((d, ErrorKind::Digit)))
);
assert_eq!(digit1(c), Err(Err::Error((c, ErrorKind::Digit))));
assert_eq!(digit1(d), Err(Err::Error((d, ErrorKind::Digit))));
assert_eq!(hex_digit1::<_, (_, ErrorKind)>(a), Ok((empty, a)));
assert_eq!(hex_digit1::<_, (_, ErrorKind)>(b), Ok((empty, b)));
assert_eq!(hex_digit1::<_, (_, ErrorKind)>(c), Ok((empty, c)));
assert_eq!(hex_digit1::<_, (_, ErrorKind)>(d), Ok(("zé12".as_bytes(), &b"a"[..])));
assert_eq!(
hex_digit1(e),
Err(Err::Error((e, ErrorKind::HexDigit)))
);
assert_eq!(
oct_digit1(a),
Err(Err::Error((a, ErrorKind::OctDigit)))
hex_digit1::<_, (_, ErrorKind)>(d),
Ok(("zé12".as_bytes(), &b"a"[..]))
);
assert_eq!(hex_digit1(e), Err(Err::Error((e, ErrorKind::HexDigit))));
assert_eq!(oct_digit1(a), Err(Err::Error((a, ErrorKind::OctDigit))));
assert_eq!(oct_digit1::<_, (_, ErrorKind)>(b), Ok((empty, b)));
assert_eq!(
oct_digit1(c),
Err(Err::Error((c, ErrorKind::OctDigit)))
);
assert_eq!(
oct_digit1(d),
Err(Err::Error((d, ErrorKind::OctDigit)))
);
assert_eq!(oct_digit1(c), Err(Err::Error((c, ErrorKind::OctDigit))));
assert_eq!(oct_digit1(d), Err(Err::Error((d, ErrorKind::OctDigit))));
assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(a), Ok((empty, a)));
//assert_eq!(fix_error!(b,(), alphanumeric), Ok((empty, b)));
assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(c), Ok((empty, c)));
assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(d), Ok(("é12".as_bytes(), &b"az"[..])));
assert_eq!(
alphanumeric1::<_, (_, ErrorKind)>(d),
Ok(("é12".as_bytes(), &b"az"[..]))
);
assert_eq!(space1::<_, (_, ErrorKind)>(e), Ok((empty, e)));
assert_eq!(space1::<_, (_, ErrorKind)>(f), Ok((&b";"[..], &b" "[..])));
}
@ -799,46 +781,22 @@ mod tests {
let d = "azé12";
let e = " ";
assert_eq!(alpha1::<_, (_, ErrorKind)>(a), Ok((empty, a)));
assert_eq!(
alpha1(b),
Err(Err::Error((b, ErrorKind::Alpha)))
);
assert_eq!(alpha1(b), Err(Err::Error((b, ErrorKind::Alpha))));
assert_eq!(alpha1::<_, (_, ErrorKind)>(c), Ok((&c[1..], &"a"[..])));
assert_eq!(alpha1::<_, (_, ErrorKind)>(d), Ok(("é12", &"az"[..])));
assert_eq!(
digit1(a),
Err(Err::Error((a, ErrorKind::Digit)))
);
assert_eq!(digit1(a), Err(Err::Error((a, ErrorKind::Digit))));
assert_eq!(digit1::<_, (_, ErrorKind)>(b), Ok((empty, b)));
assert_eq!(
digit1(c),
Err(Err::Error((c, ErrorKind::Digit)))
);
assert_eq!(
digit1(d),
Err(Err::Error((d, ErrorKind::Digit)))
);
assert_eq!(digit1(c), Err(Err::Error((c, ErrorKind::Digit))));
assert_eq!(digit1(d), Err(Err::Error((d, ErrorKind::Digit))));
assert_eq!(hex_digit1::<_, (_, ErrorKind)>(a), Ok((empty, a)));
assert_eq!(hex_digit1::<_, (_, ErrorKind)>(b), Ok((empty, b)));
assert_eq!(hex_digit1::<_, (_, ErrorKind)>(c), Ok((empty, c)));
assert_eq!(hex_digit1::<_, (_, ErrorKind)>(d), Ok(("zé12", &"a"[..])));
assert_eq!(
hex_digit1(e),
Err(Err::Error((e, ErrorKind::HexDigit)))
);
assert_eq!(
oct_digit1(a),
Err(Err::Error((a, ErrorKind::OctDigit)))
);
assert_eq!(hex_digit1(e), Err(Err::Error((e, ErrorKind::HexDigit))));
assert_eq!(oct_digit1(a), Err(Err::Error((a, ErrorKind::OctDigit))));
assert_eq!(oct_digit1::<_, (_, ErrorKind)>(b), Ok((empty, b)));
assert_eq!(
oct_digit1(c),
Err(Err::Error((c, ErrorKind::OctDigit)))
);
assert_eq!(
oct_digit1(d),
Err(Err::Error((d, ErrorKind::OctDigit)))
);
assert_eq!(oct_digit1(c), Err(Err::Error((c, ErrorKind::OctDigit))));
assert_eq!(oct_digit1(d), Err(Err::Error((d, ErrorKind::OctDigit))));
assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(a), Ok((empty, a)));
//assert_eq!(fix_error!(b,(), alphanumeric), Ok((empty, b)));
assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(c), Ok((empty, c)));
@ -903,7 +861,10 @@ mod tests {
#[test]
fn is_not_line_ending_bytes() {
let a: &[u8] = b"ab12cd\nefgh";
assert_eq!(not_line_ending::<_, (_, ErrorKind)>(a), Ok((&b"\nefgh"[..], &b"ab12cd"[..])));
assert_eq!(
not_line_ending::<_, (_, ErrorKind)>(a),
Ok((&b"\nefgh"[..], &b"ab12cd"[..]))
);
let b: &[u8] = b"ab12cd\nefgh\nijkl";
assert_eq!(
@ -918,12 +879,14 @@ mod tests {
);
let d: &[u8] = b"ab12cd";
assert_eq!(not_line_ending::<_, (_, ErrorKind)>(d), Ok((&[][..], &d[..])));
assert_eq!(
not_line_ending::<_, (_, ErrorKind)>(d),
Ok((&[][..], &d[..]))
);
}
#[test]
fn is_not_line_ending_str() {
/*
let a: &str = "ab12cd\nefgh";
assert_eq!(not_line_ending(a), Ok((&"\nefgh"[..], &"ab12cd"[..])));
@ -942,10 +905,7 @@ mod tests {
*/
let f = "βèƒôřè\rÂßÇáƒƭèř";
assert_eq!(
not_line_ending(f),
Err(Err::Error((f, ErrorKind::Tag)))
);
assert_eq!(not_line_ending(f), Err(Err::Error((f, ErrorKind::Tag))));
let g2: &str = "ab12cd";
assert_eq!(not_line_ending::<_, (_, ErrorKind)>(g2), Ok(("", g2)));
@ -1047,14 +1007,20 @@ mod tests {
#[test]
fn cr_lf() {
assert_parse!(crlf(&b"\r\na"[..]), Ok((&b"a"[..], &b"\r\n"[..])));
assert_parse!(crlf(&b"\r"[..]), Err(Err::Error(error_position!(&b"\r"[..], ErrorKind::CrLf))));
assert_parse!(
crlf(&b"\r"[..]),
Err(Err::Error(error_position!(&b"\r"[..], ErrorKind::CrLf)))
);
assert_parse!(
crlf(&b"\ra"[..]),
Err(Err::Error(error_position!(&b"\ra"[..], ErrorKind::CrLf)))
);
assert_parse!(crlf("\r\na"), Ok(("a", "\r\n")));
assert_parse!(crlf("\r"), Err(Err::Error(error_position!(&"\r"[..], ErrorKind::CrLf))));
assert_parse!(
crlf("\r"),
Err(Err::Error(error_position!(&"\r"[..], ErrorKind::CrLf)))
);
assert_parse!(
crlf("\ra"),
Err(Err::Error(error_position!("\ra", ErrorKind::CrLf)))
@ -1065,7 +1031,10 @@ mod tests {
fn end_of_line() {
assert_parse!(line_ending(&b"\na"[..]), Ok((&b"a"[..], &b"\n"[..])));
assert_parse!(line_ending(&b"\r\na"[..]), Ok((&b"a"[..], &b"\r\n"[..])));
assert_parse!(line_ending(&b"\r"[..]), Err(Err::Error(error_position!(&b"\r"[..], ErrorKind::CrLf))));
assert_parse!(
line_ending(&b"\r"[..]),
Err(Err::Error(error_position!(&b"\r"[..], ErrorKind::CrLf)))
);
assert_parse!(
line_ending(&b"\ra"[..]),
Err(Err::Error(error_position!(&b"\ra"[..], ErrorKind::CrLf)))
@ -1073,7 +1042,10 @@ mod tests {
assert_parse!(line_ending("\na"), Ok(("a", "\n")));
assert_parse!(line_ending("\r\na"), Ok(("a", "\r\n")));
assert_parse!(line_ending("\r"), Err(Err::Error(error_position!(&"\r"[..], ErrorKind::CrLf))));
assert_parse!(
line_ending("\r"),
Err(Err::Error(error_position!(&"\r"[..], ErrorKind::CrLf)))
);
assert_parse!(
line_ending("\ra"),
Err(Err::Error(error_position!("\ra", ErrorKind::CrLf)))

View File

@ -57,8 +57,8 @@ macro_rules! char (
#[cfg(test)]
mod tests {
use crate::internal::Err;
use crate::error::ErrorKind;
use crate::internal::Err;
#[test]
fn one_of() {

View File

@ -5,8 +5,8 @@
#[macro_use]
mod macros;
pub mod streaming;
pub mod complete;
pub mod streaming;
/// Tests if byte is ASCII alphabetic: A-Z, a-z
///
@ -98,4 +98,3 @@ pub fn is_alphanumeric(chr: u8) -> bool {
pub fn is_space(chr: u8) -> bool {
chr == b' ' || chr == b'\t'
}

View File

@ -2,8 +2,8 @@
//!
//! functions recognizing specific characters
use crate::internal::{Err, IResult, Needed};
use crate::error::ParseError;
use crate::internal::{Err, IResult, Needed};
use crate::lib::std::ops::{Range, RangeFrom, RangeTo};
use crate::traits::{AsChar, FindToken, InputIter, InputLength, InputTakeAtPosition, Slice};
use crate::traits::{Compare, CompareResult};
@ -35,9 +35,7 @@ where
(&c, b)
}) {
None => Err(Err::Incomplete(Needed::new(1))),
Some((_, false)) => {
Err(Err::Error(Error::from_char(i, c)))
}
Some((_, false)) => Err(Err::Error(Error::from_char(i, c))),
Some((c, true)) => Ok((i.slice(c.len()..), c.as_char())),
}
}
@ -157,9 +155,7 @@ where
let c = item.as_char();
c == '\r' || c == '\n'
}) {
None => {
Err(Err::Incomplete(Needed::Unknown))
}
None => Err(Err::Incomplete(Needed::Unknown)),
Some(index) => {
let mut it = input.slice(index..).iter_elements();
let nth = it.next().unwrap().as_char();
@ -648,8 +644,8 @@ where
#[cfg(test)]
mod tests {
use super::*;
use crate::internal::{Err, Needed};
use crate::error::ErrorKind;
use crate::internal::{Err, Needed};
macro_rules! assert_parse(
($left: expr, $right: expr) => {
@ -674,51 +670,60 @@ mod tests {
let f: &[u8] = b" ;";
//assert_eq!(alpha1::<_, (_, ErrorKind)>(a), Err(Err::Incomplete(Needed::new(1))));
assert_parse!(alpha1(a), Err(Err::Incomplete(Needed::new(1))));
assert_eq!(
alpha1(b),
Err(Err::Error((b, ErrorKind::Alpha)))
);
assert_eq!(alpha1(b), Err(Err::Error((b, ErrorKind::Alpha))));
assert_eq!(alpha1::<_, (_, ErrorKind)>(c), Ok((&c[1..], &b"a"[..])));
assert_eq!(alpha1::<_, (_, ErrorKind)>(d), Ok(("é12".as_bytes(), &b"az"[..])));
assert_eq!(
digit1(a),
Err(Err::Error((a, ErrorKind::Digit)))
alpha1::<_, (_, ErrorKind)>(d),
Ok(("é12".as_bytes(), &b"az"[..]))
);
assert_eq!(digit1::<_, (_, ErrorKind)>(b), Err(Err::Incomplete(Needed::new(1))));
assert_eq!(digit1(a), Err(Err::Error((a, ErrorKind::Digit))));
assert_eq!(
digit1(c),
Err(Err::Error((c, ErrorKind::Digit)))
digit1::<_, (_, ErrorKind)>(b),
Err(Err::Incomplete(Needed::new(1)))
);
assert_eq!(digit1(c), Err(Err::Error((c, ErrorKind::Digit))));
assert_eq!(digit1(d), Err(Err::Error((d, ErrorKind::Digit))));
assert_eq!(
hex_digit1::<_, (_, ErrorKind)>(a),
Err(Err::Incomplete(Needed::new(1)))
);
assert_eq!(
digit1(d),
Err(Err::Error((d, ErrorKind::Digit)))
);
assert_eq!(hex_digit1::<_, (_, ErrorKind)>(a), Err(Err::Incomplete(Needed::new(1))));
assert_eq!(hex_digit1::<_, (_, ErrorKind)>(b), Err(Err::Incomplete(Needed::new(1))));
assert_eq!(hex_digit1::<_, (_, ErrorKind)>(c), Err(Err::Incomplete(Needed::new(1))));
assert_eq!(hex_digit1::<_, (_, ErrorKind)>(d), Ok(("zé12".as_bytes(), &b"a"[..])));
assert_eq!(
hex_digit1(e),
Err(Err::Error((e, ErrorKind::HexDigit)))
hex_digit1::<_, (_, ErrorKind)>(b),
Err(Err::Incomplete(Needed::new(1)))
);
assert_eq!(
oct_digit1(a),
Err(Err::Error((a, ErrorKind::OctDigit)))
);
assert_eq!(oct_digit1::<_, (_, ErrorKind)>(b), Err(Err::Incomplete(Needed::new(1))));
assert_eq!(
oct_digit1(c),
Err(Err::Error((c, ErrorKind::OctDigit)))
hex_digit1::<_, (_, ErrorKind)>(c),
Err(Err::Incomplete(Needed::new(1)))
);
assert_eq!(
oct_digit1(d),
Err(Err::Error((d, ErrorKind::OctDigit)))
hex_digit1::<_, (_, ErrorKind)>(d),
Ok(("zé12".as_bytes(), &b"a"[..]))
);
assert_eq!(hex_digit1(e), Err(Err::Error((e, ErrorKind::HexDigit))));
assert_eq!(oct_digit1(a), Err(Err::Error((a, ErrorKind::OctDigit))));
assert_eq!(
oct_digit1::<_, (_, ErrorKind)>(b),
Err(Err::Incomplete(Needed::new(1)))
);
assert_eq!(oct_digit1(c), Err(Err::Error((c, ErrorKind::OctDigit))));
assert_eq!(oct_digit1(d), Err(Err::Error((d, ErrorKind::OctDigit))));
assert_eq!(
alphanumeric1::<_, (_, ErrorKind)>(a),
Err(Err::Incomplete(Needed::new(1)))
);
assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(a), Err(Err::Incomplete(Needed::new(1))));
//assert_eq!(fix_error!(b,(), alphanumeric1), Ok((empty, b)));
assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(c), Err(Err::Incomplete(Needed::new(1))));
assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(d), Ok(("é12".as_bytes(), &b"az"[..])));
assert_eq!(space1::<_, (_, ErrorKind)>(e), Err(Err::Incomplete(Needed::new(1))));
assert_eq!(
alphanumeric1::<_, (_, ErrorKind)>(c),
Err(Err::Incomplete(Needed::new(1)))
);
assert_eq!(
alphanumeric1::<_, (_, ErrorKind)>(d),
Ok(("é12".as_bytes(), &b"az"[..]))
);
assert_eq!(
space1::<_, (_, ErrorKind)>(e),
Err(Err::Incomplete(Needed::new(1)))
);
assert_eq!(space1::<_, (_, ErrorKind)>(f), Ok((&b";"[..], &b" "[..])));
}
@ -730,52 +735,55 @@ mod tests {
let c = "a123";
let d = "azé12";
let e = " ";
assert_eq!(alpha1::<_, (_, ErrorKind)>(a), Err(Err::Incomplete(Needed::new(1))));
assert_eq!(
alpha1(b),
Err(Err::Error((b, ErrorKind::Alpha)))
alpha1::<_, (_, ErrorKind)>(a),
Err(Err::Incomplete(Needed::new(1)))
);
assert_eq!(alpha1(b), Err(Err::Error((b, ErrorKind::Alpha))));
assert_eq!(alpha1::<_, (_, ErrorKind)>(c), Ok((&c[1..], &"a"[..])));
assert_eq!(alpha1::<_, (_, ErrorKind)>(d), Ok(("é12", &"az"[..])));
assert_eq!(digit1(a), Err(Err::Error((a, ErrorKind::Digit))));
assert_eq!(
digit1(a),
Err(Err::Error((a, ErrorKind::Digit)))
digit1::<_, (_, ErrorKind)>(b),
Err(Err::Incomplete(Needed::new(1)))
);
assert_eq!(digit1::<_, (_, ErrorKind)>(b), Err(Err::Incomplete(Needed::new(1))));
assert_eq!(digit1(c), Err(Err::Error((c, ErrorKind::Digit))));
assert_eq!(digit1(d), Err(Err::Error((d, ErrorKind::Digit))));
assert_eq!(
digit1(c),
Err(Err::Error((c, ErrorKind::Digit)))
hex_digit1::<_, (_, ErrorKind)>(a),
Err(Err::Incomplete(Needed::new(1)))
);
assert_eq!(
digit1(d),
Err(Err::Error((d, ErrorKind::Digit)))
hex_digit1::<_, (_, ErrorKind)>(b),
Err(Err::Incomplete(Needed::new(1)))
);
assert_eq!(
hex_digit1::<_, (_, ErrorKind)>(c),
Err(Err::Incomplete(Needed::new(1)))
);
assert_eq!(hex_digit1::<_, (_, ErrorKind)>(a), Err(Err::Incomplete(Needed::new(1))));
assert_eq!(hex_digit1::<_, (_, ErrorKind)>(b), Err(Err::Incomplete(Needed::new(1))));
assert_eq!(hex_digit1::<_, (_, ErrorKind)>(c), Err(Err::Incomplete(Needed::new(1))));
assert_eq!(hex_digit1::<_, (_, ErrorKind)>(d), Ok(("zé12", &"a"[..])));
assert_eq!(hex_digit1(e), Err(Err::Error((e, ErrorKind::HexDigit))));
assert_eq!(oct_digit1(a), Err(Err::Error((a, ErrorKind::OctDigit))));
assert_eq!(
hex_digit1(e),
Err(Err::Error((e, ErrorKind::HexDigit)))
oct_digit1::<_, (_, ErrorKind)>(b),
Err(Err::Incomplete(Needed::new(1)))
);
assert_eq!(oct_digit1(c), Err(Err::Error((c, ErrorKind::OctDigit))));
assert_eq!(oct_digit1(d), Err(Err::Error((d, ErrorKind::OctDigit))));
assert_eq!(
oct_digit1(a),
Err(Err::Error((a, ErrorKind::OctDigit)))
alphanumeric1::<_, (_, ErrorKind)>(a),
Err(Err::Incomplete(Needed::new(1)))
);
assert_eq!(oct_digit1::<_, (_, ErrorKind)>(b), Err(Err::Incomplete(Needed::new(1))));
assert_eq!(
oct_digit1(c),
Err(Err::Error((c, ErrorKind::OctDigit)))
);
assert_eq!(
oct_digit1(d),
Err(Err::Error((d, ErrorKind::OctDigit)))
);
assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(a), Err(Err::Incomplete(Needed::new(1))));
//assert_eq!(fix_error!(b,(), alphanumeric1), Ok((empty, b)));
assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(c), Err(Err::Incomplete(Needed::new(1))));
assert_eq!(
alphanumeric1::<_, (_, ErrorKind)>(c),
Err(Err::Incomplete(Needed::new(1)))
);
assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(d), Ok(("é12", "az")));
assert_eq!(space1::<_, (_, ErrorKind)>(e), Err(Err::Incomplete(Needed::new(1))));
assert_eq!(
space1::<_, (_, ErrorKind)>(e),
Err(Err::Incomplete(Needed::new(1)))
);
}
use crate::traits::Offset;
@ -835,7 +843,10 @@ mod tests {
#[test]
fn is_not_line_ending_bytes() {
let a: &[u8] = b"ab12cd\nefgh";
assert_eq!(not_line_ending::<_, (_, ErrorKind)>(a), Ok((&b"\nefgh"[..], &b"ab12cd"[..])));
assert_eq!(
not_line_ending::<_, (_, ErrorKind)>(a),
Ok((&b"\nefgh"[..], &b"ab12cd"[..]))
);
let b: &[u8] = b"ab12cd\nefgh\nijkl";
assert_eq!(
@ -850,7 +861,10 @@ mod tests {
);
let d: &[u8] = b"ab12cd";
assert_eq!(not_line_ending::<_, (_, ErrorKind)>(d), Err(Err::Incomplete(Needed::Unknown)));
assert_eq!(
not_line_ending::<_, (_, ErrorKind)>(d),
Err(Err::Incomplete(Needed::Unknown))
);
}
#[test]
@ -873,13 +887,13 @@ mod tests {
*/
let f = "βèƒôřè\rÂßÇáƒƭèř";
assert_eq!(
not_line_ending(f),
Err(Err::Error((f, ErrorKind::Tag)))
);
assert_eq!(not_line_ending(f), Err(Err::Error((f, ErrorKind::Tag))));
let g2: &str = "ab12cd";
assert_eq!(not_line_ending::<_, (_, ErrorKind)>(g2), Err(Err::Incomplete(Needed::Unknown)));
assert_eq!(
not_line_ending::<_, (_, ErrorKind)>(g2),
Err(Err::Incomplete(Needed::Unknown))
);
}
#[test]
@ -993,7 +1007,10 @@ mod tests {
fn end_of_line() {
assert_parse!(line_ending(&b"\na"[..]), Ok((&b"a"[..], &b"\n"[..])));
assert_parse!(line_ending(&b"\r\na"[..]), Ok((&b"a"[..], &b"\r\n"[..])));
assert_parse!(line_ending(&b"\r"[..]), Err(Err::Incomplete(Needed::new(2))));
assert_parse!(
line_ending(&b"\r"[..]),
Err(Err::Incomplete(Needed::new(2)))
);
assert_parse!(
line_ending(&b"\ra"[..]),
Err(Err::Error(error_position!(&b"\ra"[..], ErrorKind::CrLf)))

View File

@ -970,9 +970,9 @@ macro_rules! recognize (
#[cfg(test)]
mod tests {
use crate::internal::{Err, IResult, Needed};
use crate::error::ParseError;
use crate::error::ErrorKind;
use crate::error::ParseError;
use crate::internal::{Err, IResult, Needed};
#[cfg(feature = "alloc")]
use crate::lib::std::boxed::Box;
@ -1100,7 +1100,6 @@ mod tests {
}
}
#[test]
#[cfg(feature = "alloc")]
fn cond() {
@ -1186,10 +1185,7 @@ mod tests {
assert_eq!(
res,
Err(Err::Error(error_position!(
"ab",
ErrorKind::ParseTo
)))
Err(Err::Error(error_position!("ab", ErrorKind::ParseTo)))
);
let res: IResult<_, _, (&str, ErrorKind)> = parse_to!("42", usize);
@ -1197,5 +1193,4 @@ mod tests {
assert_eq!(res, Ok(("", 42)));
//assert_eq!(ErrorKind::convert(ErrorKind::ParseTo), ErrorKind::ParseTo::<u64>);
}
}

View File

@ -5,16 +5,16 @@
#[cfg(feature = "alloc")]
use crate::lib::std::boxed::Box;
use crate::error::ErrorKind;
use crate::error::ParseError;
use crate::internal::*;
use crate::lib::std::borrow::Borrow;
#[cfg(feature = "std")]
use crate::lib::std::fmt::Debug;
use crate::internal::*;
use crate::error::ParseError;
use crate::traits::{AsChar, InputIter, InputLength, InputTakeAtPosition, ParseTo};
use crate::lib::std::ops::{Range, RangeFrom, RangeTo};
use crate::lib::std::borrow::Borrow;
use crate::traits::{Compare, CompareResult, Offset, Slice};
use crate::error::ErrorKind;
use crate::lib::std::mem::transmute;
use crate::lib::std::ops::{Range, RangeFrom, RangeTo};
use crate::traits::{AsChar, InputIter, InputLength, InputTakeAtPosition, ParseTo};
use crate::traits::{Compare, CompareResult, Offset, Slice};
#[macro_use]
mod macros;
@ -112,7 +112,10 @@ where
/// assert_eq!(parse("123456"), Err(Err::Error(("123456", ErrorKind::MapRes))));
/// # }
/// ```
pub fn map_res<I: Clone, O1, O2, E: ParseError<I>, E2, F, G>(mut first: F, second: G) -> impl FnMut(I) -> IResult<I, O2, E>
pub fn map_res<I: Clone, O1, O2, E: ParseError<I>, E2, F, G>(
mut first: F,
second: G,
) -> impl FnMut(I) -> IResult<I, O2, E>
where
F: Parser<I, O1, E>,
G: Fn(O1) -> Result<O2, E2>,
@ -128,7 +131,11 @@ where
}
#[doc(hidden)]
pub fn map_resc<I: Clone, O1, O2, E: ParseError<I>, E2, F, G>(input: I, first: F, second: G) -> IResult<I, O2, E>
pub fn map_resc<I: Clone, O1, O2, E: ParseError<I>, E2, F, G>(
input: I,
first: F,
second: G,
) -> IResult<I, O2, E>
where
F: Fn(I) -> IResult<I, O1, E>,
G: Fn(O1) -> Result<O2, E2>,
@ -157,7 +164,10 @@ where
/// assert_eq!(parse("123456"), Err(Err::Error(("123456", ErrorKind::MapOpt))));
/// # }
/// ```
pub fn map_opt<I: Clone, O1, O2, E: ParseError<I>, F, G>(mut first: F, second: G) -> impl FnMut(I) -> IResult<I, O2, E>
pub fn map_opt<I: Clone, O1, O2, E: ParseError<I>, F, G>(
mut first: F,
second: G,
) -> impl FnMut(I) -> IResult<I, O2, E>
where
F: Parser<I, O1, E>,
G: Fn(O1) -> Option<O2>,
@ -173,7 +183,11 @@ where
}
#[doc(hidden)]
pub fn map_optc<I: Clone, O1, O2, E: ParseError<I>, F, G>(input: I, first: F, second: G) -> IResult<I, O2, E>
pub fn map_optc<I: Clone, O1, O2, E: ParseError<I>, F, G>(
input: I,
first: F,
second: G,
) -> IResult<I, O2, E>
where
F: Fn(I) -> IResult<I, O1, E>,
G: Fn(O1) -> Option<O2>,
@ -198,7 +212,10 @@ where
/// assert_eq!(parse("123"), Err(Err::Error(("123", ErrorKind::Eof))));
/// # }
/// ```
pub fn map_parser<I: Clone, O1, O2, E: ParseError<I>, F, G>(mut first: F, mut second: G) -> impl FnMut(I) -> IResult<I, O2, E>
pub fn map_parser<I: Clone, O1, O2, E: ParseError<I>, F, G>(
mut first: F,
mut second: G,
) -> impl FnMut(I) -> IResult<I, O2, E>
where
F: Parser<I, O1, E>,
G: Parser<O1, O2, E>,
@ -212,7 +229,11 @@ where
}
#[doc(hidden)]
pub fn map_parserc<I: Clone, O1, O2, E: ParseError<I>, F, G>(input: I, first: F, second: G) -> IResult<I, O2, E>
pub fn map_parserc<I: Clone, O1, O2, E: ParseError<I>, F, G>(
input: I,
first: F,
second: G,
) -> IResult<I, O2, E>
where
F: Fn(I) -> IResult<I, O1, E>,
G: Fn(O1) -> IResult<O1, O2, E>,
@ -237,11 +258,14 @@ where
/// assert_eq!(parse(&[4, 0, 1, 2][..]), Err(Err::Error((&[0, 1, 2][..], ErrorKind::Eof))));
/// # }
/// ```
pub fn flat_map<I, O1, O2, E: ParseError<I>, F, G, H>(mut first: F, second: G) -> impl FnMut(I) -> IResult<I, O2, E>
pub fn flat_map<I, O1, O2, E: ParseError<I>, F, G, H>(
mut first: F,
second: G,
) -> impl FnMut(I) -> IResult<I, O2, E>
where
F: Parser<I, O1, E>,
G: Fn(O1) -> H,
H: Parser<I, O2, E>
H: Parser<I, O2, E>,
{
move |input: I| {
let (input, o1) = first.parse(input)?;
@ -266,7 +290,7 @@ where
/// assert_eq!(parser("123;"), Ok(("123;", None)));
/// # }
/// ```
pub fn opt<I:Clone, O, E: ParseError<I>, F>(mut f: F) -> impl FnMut(I) -> IResult<I, Option<O>, E>
pub fn opt<I: Clone, O, E: ParseError<I>, F>(mut f: F) -> impl FnMut(I) -> IResult<I, Option<O>, E>
where
F: Parser<I, O, E>,
{
@ -281,7 +305,7 @@ where
}
#[doc(hidden)]
pub fn optc<I:Clone, O, E: ParseError<I>, F>(input: I, f: F) -> IResult<I, Option<O>, E>
pub fn optc<I: Clone, O, E: ParseError<I>, F>(input: I, f: F) -> IResult<I, Option<O>, E>
where
F: Fn(I) -> IResult<I, O, E>,
{
@ -307,7 +331,10 @@ where
/// assert_eq!(parser(false, "123;"), Ok(("123;", None)));
/// # }
/// ```
pub fn cond<I, O, E: ParseError<I>, F>(b: bool, mut f: F) -> impl FnMut(I) -> IResult<I, Option<O>, E>
pub fn cond<I, O, E: ParseError<I>, F>(
b: bool,
mut f: F,
) -> impl FnMut(I) -> IResult<I, Option<O>, E>
where
F: Parser<I, O, E>,
{
@ -346,7 +373,7 @@ where
/// assert_eq!(parser("123;"), Err(Err::Error(("123;", ErrorKind::Alpha))));
/// # }
/// ```
pub fn peek<I:Clone, O, E: ParseError<I>, F>(mut f: F) -> impl FnMut(I) -> IResult<I, O, E>
pub fn peek<I: Clone, O, E: ParseError<I>, F>(mut f: F) -> impl FnMut(I) -> IResult<I, O, E>
where
F: Parser<I, O, E>,
{
@ -360,7 +387,7 @@ where
}
#[doc(hidden)]
pub fn peekc<I:Clone, O, E: ParseError<I>, F>(input: I, f: F) -> IResult<I, O, E>
pub fn peekc<I: Clone, O, E: ParseError<I>, F>(input: I, f: F) -> IResult<I, O, E>
where
F: Fn(I) -> IResult<I, O, E>,
{
@ -389,10 +416,8 @@ where
move |input: I| {
let i = input.clone();
match f.parse(input) {
Err(Err::Incomplete(_)) => {
Err(Err::Error(E::from_error_kind(i, ErrorKind::Complete)))
},
rest => rest
Err(Err::Incomplete(_)) => Err(Err::Error(E::from_error_kind(i, ErrorKind::Complete))),
rest => rest,
}
}
}
@ -402,7 +427,7 @@ pub fn completec<I: Clone, O, E: ParseError<I>, F>(input: I, f: F) -> IResult<I,
where
F: Fn(I) -> IResult<I, O, E>,
{
complete(f)(input)
complete(f)(input)
}
/// succeeds if all the input has been consumed by its child parser
@ -455,7 +480,10 @@ where
/// assert_eq!(parser("123abcd;"),Err(Err::Error(("123abcd;", ErrorKind::Alpha))));
/// # }
/// ```
pub fn verify<I: Clone, O1, O2, E: ParseError<I>, F, G>(mut first: F, second: G) -> impl FnMut(I) -> IResult<I, O1, E>
pub fn verify<I: Clone, O1, O2, E: ParseError<I>, F, G>(
mut first: F,
second: G,
) -> impl FnMut(I) -> IResult<I, O1, E>
where
F: Parser<I, O1, E>,
G: Fn(&O2) -> bool,
@ -475,7 +503,11 @@ where
}
#[doc(hidden)]
pub fn verifyc<I: Clone, O1, O2, E: ParseError<I>, F, G>(input: I, first: F, second: G) -> IResult<I, O1, E>
pub fn verifyc<I: Clone, O1, O2, E: ParseError<I>, F, G>(
input: I,
first: F,
second: G,
) -> IResult<I, O1, E>
where
F: Fn(I) -> IResult<I, O1, E>,
G: Fn(&O2) -> bool,
@ -500,17 +532,22 @@ where
/// assert_eq!(parser("123abcd;"), Err(Err::Error(("123abcd;", ErrorKind::Alpha))));
/// # }
/// ```
pub fn value<I, O1: Clone, O2, E: ParseError<I>, F>(val: O1, mut parser: F) -> impl FnMut(I) -> IResult<I, O1, E>
pub fn value<I, O1: Clone, O2, E: ParseError<I>, F>(
val: O1,
mut parser: F,
) -> impl FnMut(I) -> IResult<I, O1, E>
where
F: Parser<I, O2, E>,
{
move |input: I| {
parser.parse(input).map(|(i, _)| (i, val.clone()))
}
move |input: I| parser.parse(input).map(|(i, _)| (i, val.clone()))
}
#[doc(hidden)]
pub fn valuec<I, O1: Clone, O2, E: ParseError<I>, F>(input: I, val: O1, parser: F) -> IResult<I, O1, E>
pub fn valuec<I, O1: Clone, O2, E: ParseError<I>, F>(
input: I,
val: O1,
parser: F,
) -> IResult<I, O1, E>
where
F: Fn(I) -> IResult<I, O2, E>,
{
@ -570,7 +607,9 @@ where
/// assert_eq!(parser("abcd;"),Err(Err::Error((";", ErrorKind::Char))));
/// # }
/// ```
pub fn recognize<I: Clone + Offset + Slice<RangeTo<usize>>, O, E: ParseError<I>, F>(mut parser: F) -> impl FnMut(I) -> IResult<I, I, E>
pub fn recognize<I: Clone + Offset + Slice<RangeTo<usize>>, O, E: ParseError<I>, F>(
mut parser: F,
) -> impl FnMut(I) -> IResult<I, I, E>
where
F: Parser<I, O, E>,
{
@ -580,14 +619,17 @@ where
Ok((i, _)) => {
let index = input.offset(&i);
Ok((i, input.slice(..index)))
},
}
Err(e) => Err(e),
}
}
}
#[doc(hidden)]
pub fn recognizec<I: Clone + Offset + Slice<RangeTo<usize>>, O, E: ParseError<I>, F>(input: I, parser: F) -> IResult<I, I, E>
pub fn recognizec<I: Clone + Offset + Slice<RangeTo<usize>>, O, E: ParseError<I>, F>(
input: I,
parser: F,
) -> IResult<I, I, E>
where
F: Fn(I) -> IResult<I, O, E>,
{
@ -613,11 +655,9 @@ pub fn cut<I, O, E: ParseError<I>, F>(mut parser: F) -> impl FnMut(I) -> IResult
where
F: Parser<I, O, E>,
{
move |input: I| {
match parser.parse(input) {
Err(Err::Error(e)) => Err(Err::Failure(e)),
rest => rest,
}
move |input: I| match parser.parse(input) {
Err(Err::Error(e)) => Err(Err::Failure(e)),
rest => rest,
}
}
@ -650,13 +690,13 @@ where
pub fn iterator<Input, Output, Error, F>(input: Input, f: F) -> ParserIterator<Input, Error, F>
where
F: Parser<Input, Output, Error>,
Error: ParseError<Input> {
ParserIterator {
iterator: f,
input,
state: Some(State::Running),
}
Error: ParseError<Input>,
{
ParserIterator {
iterator: f,
input,
state: Some(State::Running),
}
}
/// main structure associated to the [iterator] function
@ -677,10 +717,10 @@ impl<I: Clone, E, F> ParserIterator<I, E, F> {
}
}
impl<'a, Input ,Output ,Error, F> core::iter::Iterator for &'a mut ParserIterator<Input, Error, F>
where
F: FnMut(Input) -> IResult<Input, Output, Error>,
Input: Clone
impl<'a, Input, Output, Error, F> core::iter::Iterator for &'a mut ParserIterator<Input, Error, F>
where
F: FnMut(Input) -> IResult<Input, Output, Error>,
Input: Clone,
{
type Item = Output;
@ -693,19 +733,19 @@ impl<'a, Input ,Output ,Error, F> core::iter::Iterator for &'a mut ParserIterato
self.input = i;
self.state = Some(State::Running);
Some(o)
},
}
Err(Err::Error(_)) => {
self.state = Some(State::Done);
None
},
}
Err(Err::Failure(e)) => {
self.state = Some(State::Failure(e));
None
},
}
Err(Err::Incomplete(i)) => {
self.state = Some(State::Incomplete(i));
None
},
}
}
} else {
None
@ -720,13 +760,12 @@ enum State<E> {
Incomplete(Needed),
}
#[cfg(test)]
mod tests {
use super::*;
use crate::internal::{Err, IResult, Needed};
use crate::error::ParseError;
use crate::bytes::complete::take;
use crate::error::ParseError;
use crate::internal::{Err, IResult, Needed};
use crate::number::complete::be_u8;
macro_rules! assert_parse(
@ -745,21 +784,20 @@ mod tests {
assert_eq!(res, Ok((&v2[..], ())));
}*/
/*
#[test]
fn end_of_input() {
let not_over = &b"Hello, world!"[..];
let is_over = &b""[..];
named!(eof_test, eof!());
#[test]
fn end_of_input() {
let not_over = &b"Hello, world!"[..];
let is_over = &b""[..];
named!(eof_test, eof!());
let res_not_over = eof_test(not_over);
assert_eq!(res_not_over, Err(Err::Error(error_position!(not_over, ErrorKind::Eof))));
let res_not_over = eof_test(not_over);
assert_eq!(res_not_over, Err(Err::Error(error_position!(not_over, ErrorKind::Eof))));
let res_over = eof_test(is_over);
assert_eq!(res_over, Ok((is_over, is_over)));
}
*/
let res_over = eof_test(is_over);
assert_eq!(res_over, Ok((is_over, is_over)));
}
*/
#[test]
fn rest_on_slices() {
@ -807,28 +845,46 @@ mod tests {
#[test]
fn test_flat_map() {
let input: &[u8] = &[3, 100, 101, 102, 103, 104][..];
assert_parse!(flat_map(be_u8, take)(input), Ok((&[103, 104][..], &[100, 101, 102][..])));
let input: &[u8] = &[3, 100, 101, 102, 103, 104][..];
assert_parse!(
flat_map(be_u8, take)(input),
Ok((&[103, 104][..], &[100, 101, 102][..]))
);
}
#[test]
fn test_map_opt() {
let input: &[u8] = &[50][..];
assert_parse!(map_opt(be_u8, |u| if u < 20 {Some(u)} else {None})(input), Err(Err::Error((&[50][..], ErrorKind::MapOpt))));
assert_parse!(map_opt(be_u8, |u| if u > 20 {Some(u)} else {None})(input), Ok((&[][..], 50)));
let input: &[u8] = &[50][..];
assert_parse!(
map_opt(be_u8, |u| if u < 20 { Some(u) } else { None })(input),
Err(Err::Error((&[50][..], ErrorKind::MapOpt)))
);
assert_parse!(
map_opt(be_u8, |u| if u > 20 { Some(u) } else { None })(input),
Ok((&[][..], 50))
);
}
#[test]
fn test_map_parser() {
let input: &[u8] = &[100, 101, 102, 103, 104][..];
assert_parse!(map_parser(take(4usize), take(2usize))(input), Ok((&[104][..], &[100, 101][..])));
let input: &[u8] = &[100, 101, 102, 103, 104][..];
assert_parse!(
map_parser(take(4usize), take(2usize))(input),
Ok((&[104][..], &[100, 101][..]))
);
}
#[test]
fn test_all_consuming() {
let input: &[u8] = &[100, 101, 102][..];
assert_parse!(all_consuming(take(2usize))(input), Err(Err::Error((&[102][..], ErrorKind::Eof))));
assert_parse!(all_consuming(take(3usize))(input), Ok((&[][..], &[100, 101, 102][..])));
let input: &[u8] = &[100, 101, 102][..];
assert_parse!(
all_consuming(take(2usize))(input),
Err(Err::Error((&[102][..], ErrorKind::Eof)))
);
assert_parse!(
all_consuming(take(3usize))(input),
Ok((&[][..], &[100, 101, 102][..]))
);
}
#[test]
@ -839,7 +895,10 @@ mod tests {
let mut parser1 = verify(take(3u8), |s: &[u8]| s == &b"abc"[..]);
assert_eq!(parser1(&b"abcd"[..]), Ok((&b"d"[..], &b"abc"[..])));
assert_eq!(parser1(&b"defg"[..]), Err(Err::Error((&b"defg"[..], ErrorKind::Verify))));
assert_eq!(
parser1(&b"defg"[..]),
Err(Err::Error((&b"defg"[..], ErrorKind::Verify)))
);
fn parser2(i: &[u8]) -> IResult<&[u8], u32> {
verify(crate::number::streaming::be_u32, |val: &u32| *val < 3)(i)
@ -850,9 +909,14 @@ mod tests {
#[cfg(feature = "alloc")]
fn test_verify_alloc() {
use crate::bytes::complete::take;
let mut parser1 = verify(map(take(3u8), |s: &[u8]| s.to_vec()), |s: &[u8]| s == &b"abc"[..]);
let mut parser1 = verify(map(take(3u8), |s: &[u8]| s.to_vec()), |s: &[u8]| {
s == &b"abc"[..]
});
assert_eq!(parser1(&b"abcd"[..]), Ok((&b"d"[..], (&b"abc").to_vec())));
assert_eq!(parser1(&b"defg"[..]), Err(Err::Error((&b"defg"[..], ErrorKind::Verify))));
assert_eq!(
parser1(&b"defg"[..]),
Err(Err::Error((&b"defg"[..], ErrorKind::Verify)))
);
}
}

View File

@ -132,7 +132,10 @@ use crate::internal::{Err, IResult};
/// create a new error from an input position, a static string and an existing error.
/// This is used mainly in the [context] combinator, to add user friendly information
/// to errors when backtracking through a parse tree
pub fn context<I: Clone, E: ContextError<I>, F, O>(context: &'static str, mut f: F) -> impl FnMut(I) -> IResult<I, O, E>
pub fn context<I: Clone, E: ContextError<I>, F, O>(
context: &'static str,
mut f: F,
) -> impl FnMut(I) -> IResult<I, O, E>
where
F: Parser<I, O, E>,
{
@ -157,7 +160,9 @@ pub fn convert_error(input: &str, e: VerboseError<&str>) -> crate::lib::std::str
if input.is_empty() {
match kind {
VerboseErrorKind::Char(c) => write!(&mut result, "{}: expected '{}', got empty input\n\n", i, c),
VerboseErrorKind::Char(c) => {
write!(&mut result, "{}: expected '{}', got empty input\n\n", i, c)
}
VerboseErrorKind::Context(s) => write!(&mut result, "{}: in {}, got empty input\n\n", i, s),
VerboseErrorKind::Nom(e) => write!(&mut result, "{}: in {:?}, got empty input\n\n", i, e),
}
@ -169,45 +174,56 @@ pub fn convert_error(input: &str, e: VerboseError<&str>) -> crate::lib::std::str
// Find the line that includes the subslice:
// Find the *last* newline before the substring starts
let line_begin = prefix.iter().rev().position(|&b| b == b'\n').map(|pos| offset - pos).unwrap_or(0);
let line_begin = prefix
.iter()
.rev()
.position(|&b| b == b'\n')
.map(|pos| offset - pos)
.unwrap_or(0);
// Find the full line after that newline
let line = input[line_begin..].lines().next().unwrap_or(&input[line_begin..]).trim_end();
let line = input[line_begin..]
.lines()
.next()
.unwrap_or(&input[line_begin..])
.trim_end();
// The (1-indexed) column number is the offset of our substring into that line
let column_number = line.offset(substring) + 1;
match kind {
VerboseErrorKind::Char(c) => if let Some(actual) = substring.chars().next() {
write!(
&mut result,
"{i}: at line {line_number}:\n\
VerboseErrorKind::Char(c) => {
if let Some(actual) = substring.chars().next() {
write!(
&mut result,
"{i}: at line {line_number}:\n\
{line}\n\
{caret:>column$}\n\
expected '{expected}', found {actual}\n\n",
i = i,
line_number = line_number,
line = line,
caret = '^',
column = column_number,
expected = c,
actual = actual,
)
} else {
write!(
&mut result,
"{i}: at line {line_number}:\n\
i = i,
line_number = line_number,
line = line,
caret = '^',
column = column_number,
expected = c,
actual = actual,
)
} else {
write!(
&mut result,
"{i}: at line {line_number}:\n\
{line}\n\
{caret:>column$}\n\
expected '{expected}', got end of input\n\n",
i = i,
line_number = line_number,
line = line,
caret = '^',
column = column_number,
expected = c,
)
},
i = i,
line_number = line_number,
line = line,
caret = '^',
column = column_number,
expected = c,
)
}
}
VerboseErrorKind::Context(s) => write!(
&mut result,
"{i}: at line {line_number}, in {context}:\n\

View File

@ -11,7 +11,7 @@ use core::num::NonZeroUsize;
/// The `Ok` side is a pair containing the remainder of the input (the part of the data that
/// was not parsed) and the produced value. The `Err` side contains an instance of `nom::Err`.
///
pub type IResult<I, O, E=(I,ErrorKind)> = Result<(I, O), Err<E>>;
pub type IResult<I, O, E = (I, ErrorKind)> = Result<(I, O), Err<E>>;
/// Contains information on needed data if a parser returned `Incomplete`
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
@ -84,7 +84,8 @@ impl<E> Err<E> {
/// Applies the given function to the inner error
pub fn map<E2, F>(self, f: F) -> Err<E2>
where F: FnOnce(E) -> E2
where
F: FnOnce(E) -> E2,
{
match self {
Err::Incomplete(n) => Err::Incomplete(n),
@ -95,7 +96,8 @@ impl<E> Err<E> {
/// automatically converts between errors if the underlying type supports it
pub fn convert<F>(e: Err<F>) -> Self
where E: From<F>
where
E: From<F>,
{
e.map(Into::into)
}
@ -104,7 +106,9 @@ impl<E> Err<E> {
impl<T> Err<(T, ErrorKind)> {
/// maps `Err<(T, ErrorKind)>` to `Err<(U, ErrorKind)>` with the given F: T -> U
pub fn map_input<U, F>(self, f: F) -> Err<(U, ErrorKind)>
where F: FnOnce(T) -> U {
where
F: FnOnce(T) -> U,
{
match self {
Err::Incomplete(n) => Err::Incomplete(n),
Err::Failure((input, k)) => Err::Failure((f(input), k)),
@ -169,20 +173,22 @@ pub trait Parser<I, O, E> {
fn parse(&mut self, input: I) -> IResult<I, O, E>;
/// maps a function over the result of a parser
fn map<G,O2>(self, g: G) -> Mapper<Self, G, O>
where G: Fn(O) -> O2,
Self: std::marker::Sized, {
fn map<G, O2>(self, g: G) -> Mapper<Self, G, O>
where
G: Fn(O) -> O2,
Self: std::marker::Sized,
{
Mapper {
f: self,
g,
phantom: std::marker::PhantomData,
f: self,
g,
phantom: std::marker::PhantomData,
}
}
}
impl<'a, I, O, E, F> Parser<I, O, E> for F
where
F: FnMut(I) -> IResult<I, O, E> + 'a
F: FnMut(I) -> IResult<I, O, E> + 'a,
{
fn parse(&mut self, i: I) -> IResult<I, O, E> {
self(i)
@ -196,12 +202,11 @@ pub struct Mapper<F, G, O1> {
phantom: std::marker::PhantomData<O1>,
}
impl<'a, I, O1, O2, E, F: Parser<I, O1, E>, G: Fn(O1) -> O2> Parser<I, O2, E> for Mapper<F, G, O1>
{
impl<'a, I, O1, O2, E, F: Parser<I, O1, E>, G: Fn(O1) -> O2> Parser<I, O2, E> for Mapper<F, G, O1> {
fn parse(&mut self, i: I) -> IResult<I, O2, E> {
match self.f.parse(i) {
Err(e) => Err(e),
Ok((i, o)) => Ok((i, (self.g)(o))),
Err(e) => Err(e),
Ok((i, o)) => Ok((i, (self.g)(o))),
}
}
}
@ -234,5 +239,4 @@ mod tests {
let e = Err::Error(1);
assert_eq!(e.map(|v| v + 1), Err::Error(2));
}
}

View File

@ -408,15 +408,15 @@
#[cfg(all(not(feature = "std"), feature = "alloc"))]
#[macro_use]
extern crate alloc;
#[cfg(test)]
extern crate doc_comment;
#[cfg(feature = "lexical")]
extern crate lexical_core;
extern crate memchr;
#[cfg(feature = "regexp")]
pub extern crate regex;
#[cfg(feature = "lexical")]
extern crate lexical_core;
#[cfg(nightly)]
extern crate test;
#[cfg(test)]
extern crate doc_comment;
//FIXME: reactivate doctest once https://github.com/rust-lang/rust/issues/62210 is done
//#[cfg(doctest)]
@ -434,7 +434,7 @@ pub mod lib {
#[cfg_attr(feature = "alloc", macro_use)]
pub use alloc::{boxed, string, vec};
pub use core::{cmp, convert, fmt, iter, mem, ops, option, result, slice, str, borrow};
pub use core::{borrow, cmp, convert, fmt, iter, mem, ops, option, result, slice, str};
/// internal reproduction of std prelude
pub mod prelude {
@ -445,7 +445,10 @@ pub mod lib {
#[cfg(feature = "std")]
/// internal std exports for no_std compatibility
pub mod std {
pub use std::{alloc, boxed, cmp, collections, convert, fmt, hash, iter, mem, ops, option, result, slice, str, string, vec, borrow};
pub use std::{
alloc, borrow, boxed, cmp, collections, convert, fmt, hash, iter, mem, ops, option, result,
slice, str, string, vec,
};
/// internal reproduction of std prelude
pub mod prelude {
@ -457,11 +460,11 @@ pub mod lib {
pub use regex;
}
pub use self::traits::*;
pub use self::util::*;
pub use self::bits::*;
pub use self::internal::*;
pub use self::methods::*;
pub use self::bits::*;
pub use self::traits::*;
pub use self::util::*;
pub use self::whitespace::*;
#[cfg(feature = "regexp")]

View File

@ -17,4 +17,3 @@ macro_rules! call_m (
macro_rules! apply_m (
($($args:tt)*) => (compile_error!("method combinators moved to the nom-methods crate"););
);

View File

@ -530,14 +530,14 @@ macro_rules! fold_many_m_n(
#[cfg(test)]
mod tests {
use crate::internal::{Err, IResult, Needed};
use crate::character::streaming::digit1 as digit;
use crate::error::ErrorKind;
use crate::error::ParseError;
use crate::internal::{Err, IResult, Needed};
use crate::lib::std::str::{self, FromStr};
#[cfg(feature = "alloc")]
use crate::lib::std::vec::Vec;
use crate::character::streaming::digit1 as digit;
use crate::number::streaming::{be_u16, be_u8};
use crate::error::ErrorKind;
// reproduce the tag and take macros, because of module import order
macro_rules! tag (
@ -599,7 +599,10 @@ mod tests {
let res2 = vec![&b"abcd"[..], &b"abcd"[..]];
assert_eq!(multi(b), Ok((&b"ef"[..], res2)));
assert_eq!(multi(c), Ok((&b"azerty"[..], Vec::new())));
assert_eq!(multi_empty(d), Err(Err::Error(error_position!(d, ErrorKind::SeparatedList))));
assert_eq!(
multi_empty(d),
Err(Err::Error(error_position!(d, ErrorKind::SeparatedList)))
);
//let res3 = vec![&b""[..], &b""[..], &b""[..]];
//assert_eq!(multi_empty(d),Ok((&b"abc"[..], res3)));
let res4 = vec![&b"abcd"[..], &b"abcd"[..]];
@ -629,7 +632,10 @@ mod tests {
assert_eq!(multi(a), Ok((&b"ef"[..], res1)));
let res2 = vec![&b"abcd"[..], &b"abcd"[..]];
assert_eq!(multi(b), Ok((&b"ef"[..], res2)));
assert_eq!(multi(c), Err(Err::Error(error_position!(c, ErrorKind::Tag))));
assert_eq!(
multi(c),
Err(Err::Error(error_position!(c, ErrorKind::Tag)))
);
let res3 = vec![&b"abcd"[..], &b"abcd"[..]];
assert_eq!(multi(d), Ok((&b",ef"[..], res3)));
@ -647,14 +653,20 @@ mod tests {
named!( multi_empty<&[u8],Vec<&[u8]> >, many0!(tag_empty) );
assert_eq!(multi(&b"abcdef"[..]), Ok((&b"ef"[..], vec![&b"abcd"[..]])));
assert_eq!(multi(&b"abcdabcdefgh"[..]), Ok((&b"efgh"[..], vec![&b"abcd"[..], &b"abcd"[..]])));
assert_eq!(
multi(&b"abcdabcdefgh"[..]),
Ok((&b"efgh"[..], vec![&b"abcd"[..], &b"abcd"[..]]))
);
assert_eq!(multi(&b"azerty"[..]), Ok((&b"azerty"[..], Vec::new())));
assert_eq!(multi(&b"abcdab"[..]), Err(Err::Incomplete(Needed::new(4))));
assert_eq!(multi(&b"abcd"[..]), Err(Err::Incomplete(Needed::new(4))));
assert_eq!(multi(&b""[..]), Err(Err::Incomplete(Needed::new(4))));
assert_eq!(
multi_empty(&b"abcdef"[..]),
Err(Err::Error(error_position!(&b"abcdef"[..], ErrorKind::Many0)))
Err(Err::Error(error_position!(
&b"abcdef"[..],
ErrorKind::Many0
)))
);
}
@ -682,7 +694,10 @@ mod tests {
assert_eq!(multi(a), Ok((&b"ef"[..], res1)));
let res2 = vec![&b"abcd"[..], &b"abcd"[..]];
assert_eq!(multi(b), Ok((&b"efgh"[..], res2)));
assert_eq!(multi(c), Err(Err::Error(error_position!(c, ErrorKind::Tag))));
assert_eq!(
multi(c),
Err(Err::Error(error_position!(c, ErrorKind::Tag)))
);
assert_eq!(multi(d), Err(Err::Incomplete(Needed::new(4))));
}
@ -724,7 +739,10 @@ mod tests {
named!(multi1<&[u8],Vec<&[u8]> >, many1!(tst));
let a = &b"abcdef"[..];
assert_eq!(multi1(a), Err(Err::Error(error_position!(a, ErrorKind::Tag))));
assert_eq!(
multi1(a),
Err(Err::Error(error_position!(a, ErrorKind::Tag)))
);
}
#[test]
@ -738,7 +756,10 @@ mod tests {
let d = &b"AbcdAbcdAbcdAbcdAbcdefgh"[..];
let e = &b"AbcdAb"[..];
assert_eq!(multi(a), Err(Err::Error(error_position!(&b"ef"[..], ErrorKind::Tag))));
assert_eq!(
multi(a),
Err(Err::Error(error_position!(&b"ef"[..], ErrorKind::Tag)))
);
let res1 = vec![&b"Abcd"[..], &b"Abcd"[..]];
assert_eq!(multi(b), Ok((&b"efgh"[..], res1)));
let res2 = vec![&b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..]];
@ -755,17 +776,29 @@ mod tests {
named!(tag_abc, tag!("abc"));
named!( cnt_2<&[u8], Vec<&[u8]> >, count!(tag_abc, TIMES ) );
assert_eq!(cnt_2(&b"abcabcabcdef"[..]), Ok((&b"abcdef"[..], vec![&b"abc"[..], &b"abc"[..]])));
assert_eq!(
cnt_2(&b"abcabcabcdef"[..]),
Ok((&b"abcdef"[..], vec![&b"abc"[..], &b"abc"[..]]))
);
assert_eq!(cnt_2(&b"ab"[..]), Err(Err::Incomplete(Needed::new(3))));
assert_eq!(cnt_2(&b"abcab"[..]), Err(Err::Incomplete(Needed::new(3))));
assert_eq!(cnt_2(&b"xxx"[..]), Err(Err::Error(error_position!(&b"xxx"[..], ErrorKind::Tag))));
assert_eq!(
cnt_2(&b"xxx"[..]),
Err(Err::Error(error_position!(&b"xxx"[..], ErrorKind::Tag)))
);
assert_eq!(
cnt_2(&b"xxxabcabcdef"[..]),
Err(Err::Error(error_position!(&b"xxxabcabcdef"[..], ErrorKind::Tag)))
Err(Err::Error(error_position!(
&b"xxxabcabcdef"[..],
ErrorKind::Tag
)))
);
assert_eq!(
cnt_2(&b"abcxxxabcdef"[..]),
Err(Err::Error(error_position!(&b"xxxabcdef"[..], ErrorKind::Tag)))
Err(Err::Error(error_position!(
&b"xxxabcdef"[..],
ErrorKind::Tag
)))
);
}
@ -794,8 +827,14 @@ mod tests {
let error_2_remain = &b"abcxxxabcdef"[..];
assert_eq!(counter_2(done), Ok((rest, parsed_done)));
assert_eq!(counter_2(incomplete_1), Ok((incomplete_1, parsed_incompl_1)));
assert_eq!(counter_2(incomplete_2), Ok((incomplete_2, parsed_incompl_2)));
assert_eq!(
counter_2(incomplete_1),
Ok((incomplete_1, parsed_incompl_1))
);
assert_eq!(
counter_2(incomplete_2),
Ok((incomplete_2, parsed_incompl_2))
);
assert_eq!(counter_2(error), Ok((error_remain, parsed_err)));
assert_eq!(counter_2(error_1), Ok((error_1_remain, parsed_err_1)));
assert_eq!(counter_2(error_2), Ok((error_2_remain, parsed_err_2)));
@ -804,7 +843,7 @@ mod tests {
#[derive(Debug, Clone, PartialEq)]
pub struct NilError;
impl<I> From<(I,ErrorKind)> for NilError {
impl<I> From<(I, ErrorKind)> for NilError {
fn from(_: (I, ErrorKind)) -> Self {
NilError
}
@ -833,10 +872,16 @@ mod tests {
named!(tag_abc, tag!(&b"abc"[..]));
named!( cnt<&[u8], Vec<&[u8]> >, length_count!(number, tag_abc) );
assert_eq!(cnt(&b"2abcabcabcdef"[..]), Ok((&b"abcdef"[..], vec![&b"abc"[..], &b"abc"[..]])));
assert_eq!(
cnt(&b"2abcabcabcdef"[..]),
Ok((&b"abcdef"[..], vec![&b"abc"[..], &b"abc"[..]]))
);
assert_eq!(cnt(&b"2ab"[..]), Err(Err::Incomplete(Needed::new(3))));
assert_eq!(cnt(&b"3abcab"[..]), Err(Err::Incomplete(Needed::new(3))));
assert_eq!(cnt(&b"xxx"[..]), Err(Err::Error(error_position!(&b"xxx"[..], ErrorKind::Digit))));
assert_eq!(
cnt(&b"xxx"[..]),
Err(Err::Error(error_position!(&b"xxx"[..], ErrorKind::Digit)))
);
assert_eq!(
cnt(&b"2abcxxx"[..]),
Err(Err::Error(error_position!(&b"xxx"[..], ErrorKind::Tag)))
@ -847,9 +892,15 @@ mod tests {
fn length_data() {
named!( take<&[u8], &[u8]>, length_data!(number) );
assert_eq!(take(&b"6abcabcabcdef"[..]), Ok((&b"abcdef"[..], &b"abcabc"[..])));
assert_eq!(
take(&b"6abcabcabcdef"[..]),
Ok((&b"abcdef"[..], &b"abcabc"[..]))
);
assert_eq!(take(&b"3ab"[..]), Err(Err::Incomplete(Needed::new(3))));
assert_eq!(take(&b"xxx"[..]), Err(Err::Error(error_position!(&b"xxx"[..], ErrorKind::Digit))));
assert_eq!(
take(&b"xxx"[..]),
Err(Err::Error(error_position!(&b"xxx"[..], ErrorKind::Digit)))
);
assert_eq!(take(&b"2abcxxx"[..]), Ok((&b"cxxx"[..], &b"ab"[..])));
}
@ -859,8 +910,14 @@ mod tests {
named!(length_value_2<&[u8], (u8, u8) >, length_value!(be_u8, tuple!(be_u8, be_u8)));
let i1 = [0, 5, 6];
assert_eq!(length_value_1(&i1), Err(Err::Error(error_position!(&b""[..], ErrorKind::Complete))));
assert_eq!(length_value_2(&i1), Err(Err::Error(error_position!(&b""[..], ErrorKind::Complete))));
assert_eq!(
length_value_1(&i1),
Err(Err::Error(error_position!(&b""[..], ErrorKind::Complete)))
);
assert_eq!(
length_value_2(&i1),
Err(Err::Error(error_position!(&b""[..], ErrorKind::Complete)))
);
let i2 = [1, 5, 6, 3];
assert_eq!(
@ -894,14 +951,20 @@ mod tests {
named!( multi_empty<&[u8],Vec<&[u8]> >, fold_many0!(tag_empty, Vec::new(), fold_into_vec) );
assert_eq!(multi(&b"abcdef"[..]), Ok((&b"ef"[..], vec![&b"abcd"[..]])));
assert_eq!(multi(&b"abcdabcdefgh"[..]), Ok((&b"efgh"[..], vec![&b"abcd"[..], &b"abcd"[..]])));
assert_eq!(
multi(&b"abcdabcdefgh"[..]),
Ok((&b"efgh"[..], vec![&b"abcd"[..], &b"abcd"[..]]))
);
assert_eq!(multi(&b"azerty"[..]), Ok((&b"azerty"[..], Vec::new())));
assert_eq!(multi(&b"abcdab"[..]), Err(Err::Incomplete(Needed::new(4))));
assert_eq!(multi(&b"abcd"[..]), Err(Err::Incomplete(Needed::new(4))));
assert_eq!(multi(&b""[..]), Err(Err::Incomplete(Needed::new(4))));
assert_eq!(
multi_empty(&b"abcdef"[..]),
Err(Err::Error(error_position!(&b"abcdef"[..], ErrorKind::Many0)))
Err(Err::Error(error_position!(
&b"abcdef"[..],
ErrorKind::Many0
)))
);
}
@ -923,7 +986,10 @@ mod tests {
assert_eq!(multi(a), Ok((&b"ef"[..], res1)));
let res2 = vec![&b"abcd"[..], &b"abcd"[..]];
assert_eq!(multi(b), Ok((&b"efgh"[..], res2)));
assert_eq!(multi(c), Err(Err::Error(error_position!(c, ErrorKind::Many1))));
assert_eq!(
multi(c),
Err(Err::Error(error_position!(c, ErrorKind::Many1)))
);
assert_eq!(multi(d), Err(Err::Incomplete(Needed::new(4))));
}
@ -942,7 +1008,10 @@ mod tests {
let d = &b"AbcdAbcdAbcdAbcdAbcdefgh"[..];
let e = &b"AbcdAb"[..];
assert_eq!(multi(a), Err(Err::Error(error_position!(a, ErrorKind::ManyMN))));
assert_eq!(
multi(a),
Err(Err::Error(error_position!(a, ErrorKind::ManyMN)))
);
let res1 = vec![&b"Abcd"[..], &b"Abcd"[..]];
assert_eq!(multi(b), Ok((&b"efgh"[..], res1)));
let res2 = vec![&b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..]];
@ -963,7 +1032,10 @@ mod tests {
assert_eq!(count0_nums(&b"123,45,junk"[..]), Ok((&b"junk"[..], 2)));
assert_eq!(count0_nums(&b"1,2,3,4,5,6,7,8,9,0,junk"[..]), Ok((&b"junk"[..], 10)));
assert_eq!(
count0_nums(&b"1,2,3,4,5,6,7,8,9,0,junk"[..]),
Ok((&b"junk"[..], 10))
);
assert_eq!(count0_nums(&b"hello"[..]), Ok((&b"hello"[..], 0)));
}
@ -977,12 +1049,17 @@ mod tests {
assert_eq!(count1_nums(&b"123,45,junk"[..]), Ok((&b"junk"[..], 2)));
assert_eq!(count1_nums(&b"1,2,3,4,5,6,7,8,9,0,junk"[..]), Ok((&b"junk"[..], 10)));
assert_eq!(
count1_nums(&b"1,2,3,4,5,6,7,8,9,0,junk"[..]),
Ok((&b"junk"[..], 10))
);
assert_eq!(
count1_nums(&b"hello"[..]),
Err(Err::Error(error_position!(&b"hello"[..], ErrorKind::Many1Count)))
Err(Err::Error(error_position!(
&b"hello"[..],
ErrorKind::Many1Count
)))
);
}
}

View File

@ -3,12 +3,12 @@
#[macro_use]
mod macros;
use crate::internal::{Err, IResult, Needed, Parser};
use crate::error::ErrorKind;
use crate::error::ParseError;
use crate::traits::{InputLength, InputTake, ToUsize};
use crate::internal::{Err, IResult, Needed, Parser};
#[cfg(feature = "alloc")]
use crate::lib::std::vec::Vec;
use crate::error::ErrorKind;
use crate::traits::{InputLength, InputTake, ToUsize};
/// Repeats the embedded parser until it fails
/// and returns the results in a `Vec`.
@ -165,7 +165,10 @@ where
/// assert_eq!(parser("abcendefg"), Ok(("efg", (vec!["abc"], "end"))));
/// ```
#[cfg(feature = "alloc")]
pub fn many_till<I, O, P, E, F, G>(mut f: F, mut g: G) -> impl FnMut(I) -> IResult<I, (Vec<O>, P), E>
pub fn many_till<I, O, P, E, F, G>(
mut f: F,
mut g: G,
) -> impl FnMut(I) -> IResult<I, (Vec<O>, P), E>
where
I: Clone + PartialEq,
F: Parser<I, O, E>,
@ -180,8 +183,7 @@ where
Ok((i1, o)) => return Ok((i1, (res, o))),
Err(Err::Error(_)) => {
match f.parse(i.clone()) {
Err(Err::Error(err)) =>
return Err(Err::Error(E::append(i, ErrorKind::ManyTill, err))),
Err(Err::Error(err)) => return Err(Err::Error(E::append(i, ErrorKind::ManyTill, err))),
Err(e) => return Err(e),
Ok((i1, o)) => {
// loop trip must always consume (otherwise infinite loops)
@ -193,7 +195,7 @@ where
i = i1;
}
}
},
}
Err(e) => return Err(e),
}
}
@ -235,7 +237,10 @@ where
/// assert_eq!(parser("def|abc"), Ok(("def|abc", vec![])));
/// ```
#[cfg(feature = "alloc")]
pub fn separated_list0<I, O, O2, E, F, G>(mut sep: G, mut f: F) -> impl FnMut(I) -> IResult<I, Vec<O>, E>
pub fn separated_list0<I, O, O2, E, F, G>(
mut sep: G,
mut f: F,
) -> impl FnMut(I) -> IResult<I, Vec<O>, E>
where
I: Clone + PartialEq,
F: Parser<I, O, E>,
@ -322,7 +327,10 @@ where
/// assert_eq!(parser("def|abc"), Err(Err::Error(("def|abc", ErrorKind::Tag))));
/// ```
#[cfg(feature = "alloc")]
pub fn separated_list1<I, O, O2, E, F, G>(mut sep: G, mut f: F) -> impl FnMut(I) -> IResult<I, Vec<O>, E>
pub fn separated_list1<I, O, O2, E, F, G>(
mut sep: G,
mut f: F,
) -> impl FnMut(I) -> IResult<I, Vec<O>, E>
where
I: Clone + PartialEq,
F: Parser<I, O, E>,
@ -335,7 +343,7 @@ where
// Parse the first element
match f.parse(i.clone()) {
Err(e)=> return Err(e),
Err(e) => return Err(e),
Ok((i1, o)) => {
if i1 == i {
return Err(Err::Error(E::from_error_kind(i1, ErrorKind::SeparatedList)));
@ -422,7 +430,7 @@ where
let mut count: usize = 0;
if n == 0 {
return Ok((i, vec!()))
return Ok((i, vec![]));
}
loop {
@ -623,7 +631,7 @@ where
F: Parser<I, O, E>,
E: ParseError<I>,
{
move |i: I | {
move |i: I| {
let mut input = i.clone();
let mut res = crate::lib::std::vec::Vec::new();
@ -844,7 +852,13 @@ where
/// assert_eq!(parser(""), Ok(("", vec![])));
/// assert_eq!(parser("abcabcabc"), Ok(("abc", vec!["abc", "abc"])));
/// ```
pub fn fold_many_m_n<I, O, E, F, G, R>(m: usize, n: usize, mut f: F, init: R, g: G) -> impl FnMut(I) ->IResult<I, R, E>
pub fn fold_many_m_n<I, O, E, F, G, R>(
m: usize,
n: usize,
mut f: F,
init: R,
g: G,
) -> impl FnMut(I) -> IResult<I, R, E>
where
I: Clone + PartialEq,
F: Parser<I, O, E>,
@ -868,10 +882,12 @@ where
input = i;
}
//FInputXMError: handle failure properly
Err(Err::Error(_)) => if count < m {
return Err(Err::Error(E::from_error_kind(i, ErrorKind::ManyMN)));
} else {
break;
Err(Err::Error(_)) => {
if count < m {
return Err(Err::Error(E::from_error_kind(i, ErrorKind::ManyMN)));
} else {
break;
}
}
Err(e) => return Err(e),
}
@ -882,7 +898,14 @@ where
}
#[doc(hidden)]
pub fn fold_many_m_nc<I, O, E, F, G, R>(i: I, m: usize, n: usize, f: F, init: R, g: G) -> IResult<I, R, E>
pub fn fold_many_m_nc<I, O, E, F, G, R>(
i: I,
m: usize,
n: usize,
f: F,
init: R,
g: G,
) -> IResult<I, R, E>
where
I: Clone + PartialEq,
F: Fn(I) -> IResult<I, O, E>,
@ -973,10 +996,9 @@ where
} else {
let (rest, i) = i.take_split(length);
match g.parse(i.clone()) {
Err(Err::Incomplete(_)) =>
Err(Err::Error(E::from_error_kind(i, ErrorKind::Complete))),
Err(Err::Incomplete(_)) => Err(Err::Error(E::from_error_kind(i, ErrorKind::Complete))),
Err(e) => Err(e),
Ok((_, o)) => Ok((rest,o)),
Ok((_, o)) => Ok((rest, o)),
}
}
}

View File

@ -815,7 +815,11 @@ where
pub fn hex_u32<'a, E: ParseError<&'a [u8]>>(input: &'a [u8]) -> IResult<&'a [u8], u32, E> {
let (i, o) = crate::bytes::complete::is_a(&b"0123456789abcdefABCDEF"[..])(input)?;
// Do not parse more than 8 characters for a u32
let (parsed, remaining) = if o.len() <= 8 { (o, i) } else { (&input[..8], &input[8..]) };
let (parsed, remaining) = if o.len() <= 8 {
(o, i)
} else {
(&input[..8], &input[8..])
};
let res = parsed
.iter()
@ -1042,32 +1046,50 @@ mod tests {
fn u24_tests() {
assert_parse!(be_u24(&[0x00, 0x00, 0x00][..]), Ok((&b""[..], 0)));
assert_parse!(be_u24(&[0x00, 0xFF, 0xFF][..]), Ok((&b""[..], 65_535_u32)));
assert_parse!(be_u24(&[0x12, 0x34, 0x56][..]), Ok((&b""[..], 1_193_046_u32)));
assert_parse!(
be_u24(&[0x12, 0x34, 0x56][..]),
Ok((&b""[..], 1_193_046_u32))
);
}
#[test]
fn i24_tests() {
assert_parse!(be_i24(&[0xFF, 0xFF, 0xFF][..]), Ok((&b""[..], -1_i32)));
assert_parse!(be_i24(&[0xFF, 0x00, 0x00][..]), Ok((&b""[..], -65_536_i32)));
assert_parse!(be_i24(&[0xED, 0xCB, 0xAA][..]), Ok((&b""[..], -1_193_046_i32)));
assert_parse!(
be_i24(&[0xED, 0xCB, 0xAA][..]),
Ok((&b""[..], -1_193_046_i32))
);
}
#[test]
fn i32_tests() {
assert_parse!(be_i32(&[0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 0)));
assert_parse!(be_i32(&[0x7f, 0xff, 0xff, 0xff][..]), Ok((&b""[..], 2_147_483_647_i32)));
assert_parse!(
be_i32(&[0x7f, 0xff, 0xff, 0xff][..]),
Ok((&b""[..], 2_147_483_647_i32))
);
assert_parse!(be_i32(&[0xff, 0xff, 0xff, 0xff][..]), Ok((&b""[..], -1)));
assert_parse!(be_i32(&[0x80, 0x00, 0x00, 0x00][..]), Ok((&b""[..], -2_147_483_648_i32)));
assert_parse!(
be_i32(&[0x80, 0x00, 0x00, 0x00][..]),
Ok((&b""[..], -2_147_483_648_i32))
);
}
#[test]
fn i64_tests() {
assert_parse!(be_i64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 0)));
assert_parse!(
be_i64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
Ok((&b""[..], 0))
);
assert_parse!(
be_i64(&[0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff][..]),
Ok((&b""[..], 9_223_372_036_854_775_807_i64))
);
assert_parse!(be_i64(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff][..]), Ok((&b""[..], -1)));
assert_parse!(
be_i64(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff][..]),
Ok((&b""[..], -1))
);
assert_parse!(
be_i64(&[0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
Ok((&b""[..], -9_223_372_036_854_775_808_i64))
@ -1078,20 +1100,46 @@ mod tests {
#[cfg(stable_i128)]
fn i128_tests() {
assert_parse!(
be_i128(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
be_i128(
&[
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00
][..]
),
Ok((&b""[..], 0))
);
assert_parse!(
be_i128(&[0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff][..]),
Ok((&b""[..], 170_141_183_460_469_231_731_687_303_715_884_105_727_i128))
be_i128(
&[
0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff
][..]
),
Ok((
&b""[..],
170_141_183_460_469_231_731_687_303_715_884_105_727_i128
))
);
assert_parse!(
be_i128(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff][..]),
be_i128(
&[
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff
][..]
),
Ok((&b""[..], -1))
);
assert_parse!(
be_i128(&[0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
Ok((&b""[..], -170_141_183_460_469_231_731_687_303_715_884_105_728_i128))
be_i128(
&[
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00
][..]
),
Ok((
&b""[..],
-170_141_183_460_469_231_731_687_303_715_884_105_728_i128
))
);
}
@ -1115,32 +1163,50 @@ mod tests {
fn le_u24_tests() {
assert_parse!(le_u24(&[0x00, 0x00, 0x00][..]), Ok((&b""[..], 0)));
assert_parse!(le_u24(&[0xFF, 0xFF, 0x00][..]), Ok((&b""[..], 65_535_u32)));
assert_parse!(le_u24(&[0x56, 0x34, 0x12][..]), Ok((&b""[..], 1_193_046_u32)));
assert_parse!(
le_u24(&[0x56, 0x34, 0x12][..]),
Ok((&b""[..], 1_193_046_u32))
);
}
#[test]
fn le_i24_tests() {
assert_parse!(le_i24(&[0xFF, 0xFF, 0xFF][..]), Ok((&b""[..], -1_i32)));
assert_parse!(le_i24(&[0x00, 0x00, 0xFF][..]), Ok((&b""[..], -65_536_i32)));
assert_parse!(le_i24(&[0xAA, 0xCB, 0xED][..]), Ok((&b""[..], -1_193_046_i32)));
assert_parse!(
le_i24(&[0xAA, 0xCB, 0xED][..]),
Ok((&b""[..], -1_193_046_i32))
);
}
#[test]
fn le_i32_tests() {
assert_parse!(le_i32(&[0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 0)));
assert_parse!(le_i32(&[0xff, 0xff, 0xff, 0x7f][..]), Ok((&b""[..], 2_147_483_647_i32)));
assert_parse!(
le_i32(&[0xff, 0xff, 0xff, 0x7f][..]),
Ok((&b""[..], 2_147_483_647_i32))
);
assert_parse!(le_i32(&[0xff, 0xff, 0xff, 0xff][..]), Ok((&b""[..], -1)));
assert_parse!(le_i32(&[0x00, 0x00, 0x00, 0x80][..]), Ok((&b""[..], -2_147_483_648_i32)));
assert_parse!(
le_i32(&[0x00, 0x00, 0x00, 0x80][..]),
Ok((&b""[..], -2_147_483_648_i32))
);
}
#[test]
fn le_i64_tests() {
assert_parse!(le_i64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 0)));
assert_parse!(
le_i64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
Ok((&b""[..], 0))
);
assert_parse!(
le_i64(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f][..]),
Ok((&b""[..], 9_223_372_036_854_775_807_i64))
);
assert_parse!(le_i64(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff][..]), Ok((&b""[..], -1)));
assert_parse!(
le_i64(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff][..]),
Ok((&b""[..], -1))
);
assert_parse!(
le_i64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80][..]),
Ok((&b""[..], -9_223_372_036_854_775_808_i64))
@ -1151,32 +1217,64 @@ mod tests {
#[cfg(stable_i128)]
fn le_i128_tests() {
assert_parse!(
le_i128(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
le_i128(
&[
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00
][..]
),
Ok((&b""[..], 0))
);
assert_parse!(
le_i128(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f][..]),
Ok((&b""[..], 170_141_183_460_469_231_731_687_303_715_884_105_727_i128))
le_i128(
&[
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x7f
][..]
),
Ok((
&b""[..],
170_141_183_460_469_231_731_687_303_715_884_105_727_i128
))
);
assert_parse!(
le_i128(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff][..]),
le_i128(
&[
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff
][..]
),
Ok((&b""[..], -1))
);
assert_parse!(
le_i128(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80][..]),
Ok((&b""[..], -170_141_183_460_469_231_731_687_303_715_884_105_728_i128))
le_i128(
&[
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80
][..]
),
Ok((
&b""[..],
-170_141_183_460_469_231_731_687_303_715_884_105_728_i128
))
);
}
#[test]
fn be_f32_tests() {
assert_parse!(be_f32(&[0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 0_f32)));
assert_parse!(be_f32(&[0x4d, 0x31, 0x1f, 0xd8][..]), Ok((&b""[..], 185_728_392_f32)));
assert_parse!(
be_f32(&[0x4d, 0x31, 0x1f, 0xd8][..]),
Ok((&b""[..], 185_728_392_f32))
);
}
#[test]
fn be_f64_tests() {
assert_parse!(be_f64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 0_f64)));
assert_parse!(
be_f64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
Ok((&b""[..], 0_f64))
);
assert_parse!(
be_f64(&[0x41, 0xa6, 0x23, 0xfb, 0x10, 0x00, 0x00, 0x00][..]),
Ok((&b""[..], 185_728_392_f64))
@ -1186,12 +1284,18 @@ mod tests {
#[test]
fn le_f32_tests() {
assert_parse!(le_f32(&[0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 0_f32)));
assert_parse!(le_f32(&[0xd8, 0x1f, 0x31, 0x4d][..]), Ok((&b""[..], 185_728_392_f32)));
assert_parse!(
le_f32(&[0xd8, 0x1f, 0x31, 0x4d][..]),
Ok((&b""[..], 185_728_392_f32))
);
}
#[test]
fn le_f64_tests() {
assert_parse!(le_f64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 0_f64)));
assert_parse!(
le_f64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
Ok((&b""[..], 0_f64))
);
assert_parse!(
le_f64(&[0x00, 0x00, 0x00, 0x10, 0xfb, 0x23, 0xa6, 0x41][..]),
Ok((&b""[..], 185_728_392_f64))
@ -1200,13 +1304,19 @@ mod tests {
#[test]
fn hex_u32_tests() {
assert_parse!(hex_u32(&b";"[..]), Err(Err::Error(error_position!(&b";"[..], ErrorKind::IsA))));
assert_parse!(
hex_u32(&b";"[..]),
Err(Err::Error(error_position!(&b";"[..], ErrorKind::IsA)))
);
assert_parse!(hex_u32(&b"ff;"[..]), Ok((&b";"[..], 255)));
assert_parse!(hex_u32(&b"1be2;"[..]), Ok((&b";"[..], 7138)));
assert_parse!(hex_u32(&b"c5a31be2;"[..]), Ok((&b";"[..], 3_315_801_058)));
assert_parse!(hex_u32(&b"C5A31be2;"[..]), Ok((&b";"[..], 3_315_801_058)));
assert_parse!(hex_u32(&b"00c5a31be2;"[..]), Ok((&b"e2;"[..], 12_952_347)));
assert_parse!(hex_u32(&b"c5a31be201;"[..]), Ok((&b"01;"[..], 3_315_801_058)));
assert_parse!(
hex_u32(&b"c5a31be201;"[..]),
Ok((&b"01;"[..], 3_315_801_058))
);
assert_parse!(hex_u32(&b"ffffffff;"[..]), Ok((&b";"[..], 4_294_967_295)));
assert_parse!(hex_u32(&b"0x1be2;"[..]), Ok((&b"x1be2;"[..], 0)));
assert_parse!(hex_u32(&b"12af"[..]), Ok((&b""[..], 0x12af)));
@ -1251,6 +1361,9 @@ mod tests {
}
let remaining_exponent = "-1.234E-";
assert_parse!(recognize_float(remaining_exponent), Err(Err::Failure(("", ErrorKind::Digit))));
assert_parse!(
recognize_float(remaining_exponent),
Err(Err::Failure(("", ErrorKind::Digit)))
);
}
}

View File

@ -199,8 +199,14 @@ mod tests {
named!(be_tst32<u32>, u32!(Endianness::Big));
named!(le_tst32<u32>, u32!(Endianness::Little));
assert_eq!(be_tst32(&[0x12, 0x00, 0x60, 0x00]), Ok((&b""[..], 302_014_464_u32)));
assert_eq!(le_tst32(&[0x12, 0x00, 0x60, 0x00]), Ok((&b""[..], 6_291_474_u32)));
assert_eq!(
be_tst32(&[0x12, 0x00, 0x60, 0x00]),
Ok((&b""[..], 302_014_464_u32))
);
assert_eq!(
le_tst32(&[0x12, 0x00, 0x60, 0x00]),
Ok((&b""[..], 6_291_474_u32))
);
named!(be_tst64<u64>, u64!(Endianness::Big));
named!(le_tst64<u64>, u64!(Endianness::Little));
@ -220,8 +226,14 @@ mod tests {
named!(be_tsti32<i32>, i32!(Endianness::Big));
named!(le_tsti32<i32>, i32!(Endianness::Little));
assert_eq!(be_tsti32(&[0x00, 0x12, 0x60, 0x00]), Ok((&b""[..], 1_204_224_i32)));
assert_eq!(le_tsti32(&[0x00, 0x12, 0x60, 0x00]), Ok((&b""[..], 6_296_064_i32)));
assert_eq!(
be_tsti32(&[0x00, 0x12, 0x60, 0x00]),
Ok((&b""[..], 1_204_224_i32))
);
assert_eq!(
le_tsti32(&[0x00, 0x12, 0x60, 0x00]),
Ok((&b""[..], 6_296_064_i32))
);
named!(be_tsti64<i64>, i64!(Endianness::Big));
named!(le_tsti64<i64>, i64!(Endianness::Little));

View File

@ -3,8 +3,8 @@
#[macro_use]
mod macros;
pub mod streaming;
pub mod complete;
pub mod streaming;
/// Configurable endianness
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
@ -14,4 +14,3 @@ pub enum Endianness {
/// little endian
Little,
}

View File

@ -785,7 +785,11 @@ pub fn hex_u32<'a, E: ParseError<&'a [u8]>>(input: &'a [u8]) -> IResult<&'a [u8]
let (i, o) = crate::bytes::streaming::is_a(&b"0123456789abcdefABCDEF"[..])(input)?;
// Do not parse more than 8 characters for a u32
let (parsed, remaining) = if o.len() <= 8 { (o, i) } else { (&input[..8], &input[8..]) };
let (parsed, remaining) = if o.len() <= 8 {
(o, i)
} else {
(&input[..8], &input[8..])
};
let res = parsed
.iter()
@ -1022,52 +1026,94 @@ mod tests {
fn u24_tests() {
assert_parse!(be_u24(&[0x00, 0x00, 0x00][..]), Ok((&b""[..], 0)));
assert_parse!(be_u24(&[0x00, 0xFF, 0xFF][..]), Ok((&b""[..], 65_535_u32)));
assert_parse!(be_u24(&[0x12, 0x34, 0x56][..]), Ok((&b""[..], 1_193_046_u32)));
assert_parse!(
be_u24(&[0x12, 0x34, 0x56][..]),
Ok((&b""[..], 1_193_046_u32))
);
assert_parse!(be_u24(&[][..]), Err(Err::Incomplete(Needed::new(3))));
assert_parse!(be_u24(&[0x00][..]), Err(Err::Incomplete(Needed::new(2))));
assert_parse!(be_u24(&[0x00, 0x00][..]), Err(Err::Incomplete(Needed::new(1))));
assert_parse!(
be_u24(&[0x00, 0x00][..]),
Err(Err::Incomplete(Needed::new(1)))
);
}
#[test]
fn i24_tests() {
assert_parse!(be_i24(&[0xFF, 0xFF, 0xFF][..]), Ok((&b""[..], -1_i32)));
assert_parse!(be_i24(&[0xFF, 0x00, 0x00][..]), Ok((&b""[..], -65_536_i32)));
assert_parse!(be_i24(&[0xED, 0xCB, 0xAA][..]), Ok((&b""[..], -1_193_046_i32)));
assert_parse!(
be_i24(&[0xED, 0xCB, 0xAA][..]),
Ok((&b""[..], -1_193_046_i32))
);
assert_parse!(be_i24(&[][..]), Err(Err::Incomplete(Needed::new(3))));
assert_parse!(be_i24(&[0x00][..]), Err(Err::Incomplete(Needed::new(2))));
assert_parse!(be_i24(&[0x00, 0x00][..]), Err(Err::Incomplete(Needed::new(1))));
assert_parse!(
be_i24(&[0x00, 0x00][..]),
Err(Err::Incomplete(Needed::new(1)))
);
}
#[test]
fn i32_tests() {
assert_parse!(be_i32(&[0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 0)));
assert_parse!(be_i32(&[0x7f, 0xff, 0xff, 0xff][..]), Ok((&b""[..], 2_147_483_647_i32)));
assert_parse!(
be_i32(&[0x7f, 0xff, 0xff, 0xff][..]),
Ok((&b""[..], 2_147_483_647_i32))
);
assert_parse!(be_i32(&[0xff, 0xff, 0xff, 0xff][..]), Ok((&b""[..], -1)));
assert_parse!(be_i32(&[0x80, 0x00, 0x00, 0x00][..]), Ok((&b""[..], -2_147_483_648_i32)));
assert_parse!(
be_i32(&[0x80, 0x00, 0x00, 0x00][..]),
Ok((&b""[..], -2_147_483_648_i32))
);
assert_parse!(be_i32(&[][..]), Err(Err::Incomplete(Needed::new(4))));
assert_parse!(be_i32(&[0x00][..]), Err(Err::Incomplete(Needed::new(3))));
assert_parse!(be_i32(&[0x00, 0x00][..]), Err(Err::Incomplete(Needed::new(2))));
assert_parse!(be_i32(&[0x00, 0x00, 0x00][..]), Err(Err::Incomplete(Needed::new(1))));
assert_parse!(
be_i32(&[0x00, 0x00][..]),
Err(Err::Incomplete(Needed::new(2)))
);
assert_parse!(
be_i32(&[0x00, 0x00, 0x00][..]),
Err(Err::Incomplete(Needed::new(1)))
);
}
#[test]
fn i64_tests() {
assert_parse!(be_i64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 0)));
assert_parse!(
be_i64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
Ok((&b""[..], 0))
);
assert_parse!(
be_i64(&[0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff][..]),
Ok((&b""[..], 9_223_372_036_854_775_807_i64))
);
assert_parse!(be_i64(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff][..]), Ok((&b""[..], -1)));
assert_parse!(
be_i64(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff][..]),
Ok((&b""[..], -1))
);
assert_parse!(
be_i64(&[0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
Ok((&b""[..], -9_223_372_036_854_775_808_i64))
);
assert_parse!(be_i64(&[][..]), Err(Err::Incomplete(Needed::new(8))));
assert_parse!(be_i64(&[0x00][..]), Err(Err::Incomplete(Needed::new(7))));
assert_parse!(be_i64(&[0x00, 0x00][..]), Err(Err::Incomplete(Needed::new(6))));
assert_parse!(be_i64(&[0x00, 0x00, 0x00][..]), Err(Err::Incomplete(Needed::new(5))));
assert_parse!(be_i64(&[0x00, 0x00, 0x00, 0x00][..]), Err(Err::Incomplete(Needed::new(4))));
assert_parse!(be_i64(&[0x00, 0x00, 0x00, 0x00, 0x00][..]), Err(Err::Incomplete(Needed::new(3))));
assert_parse!(
be_i64(&[0x00, 0x00][..]),
Err(Err::Incomplete(Needed::new(6)))
);
assert_parse!(
be_i64(&[0x00, 0x00, 0x00][..]),
Err(Err::Incomplete(Needed::new(5)))
);
assert_parse!(
be_i64(&[0x00, 0x00, 0x00, 0x00][..]),
Err(Err::Incomplete(Needed::new(4)))
);
assert_parse!(
be_i64(&[0x00, 0x00, 0x00, 0x00, 0x00][..]),
Err(Err::Incomplete(Needed::new(3)))
);
assert_parse!(
be_i64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
Err(Err::Incomplete(Needed::new(2)))
@ -1082,27 +1128,65 @@ mod tests {
#[cfg(stable_i128)]
fn i128_tests() {
assert_parse!(
be_i128(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
be_i128(
&[
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00
][..]
),
Ok((&b""[..], 0))
);
assert_parse!(
be_i128(&[0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff][..]),
Ok((&b""[..], 170_141_183_460_469_231_731_687_303_715_884_105_727_i128))
be_i128(
&[
0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff
][..]
),
Ok((
&b""[..],
170_141_183_460_469_231_731_687_303_715_884_105_727_i128
))
);
assert_parse!(
be_i128(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff][..]),
be_i128(
&[
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff
][..]
),
Ok((&b""[..], -1))
);
assert_parse!(
be_i128(&[0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
Ok((&b""[..], -170_141_183_460_469_231_731_687_303_715_884_105_728_i128))
be_i128(
&[
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00
][..]
),
Ok((
&b""[..],
-170_141_183_460_469_231_731_687_303_715_884_105_728_i128
))
);
assert_parse!(be_i128(&[][..]), Err(Err::Incomplete(Needed::new(16))));
assert_parse!(be_i128(&[0x00][..]), Err(Err::Incomplete(Needed::new(15))));
assert_parse!(be_i128(&[0x00, 0x00][..]), Err(Err::Incomplete(Needed::new(14))));
assert_parse!(be_i128(&[0x00, 0x00, 0x00][..]), Err(Err::Incomplete(Needed::new(13))));
assert_parse!(be_i128(&[0x00, 0x00, 0x00, 0x00][..]), Err(Err::Incomplete(Needed::new(12))));
assert_parse!(be_i128(&[0x00, 0x00, 0x00, 0x00, 0x00][..]), Err(Err::Incomplete(Needed::new(11))));
assert_parse!(
be_i128(&[0x00, 0x00][..]),
Err(Err::Incomplete(Needed::new(14)))
);
assert_parse!(
be_i128(&[0x00, 0x00, 0x00][..]),
Err(Err::Incomplete(Needed::new(13)))
);
assert_parse!(
be_i128(&[0x00, 0x00, 0x00, 0x00][..]),
Err(Err::Incomplete(Needed::new(12)))
);
assert_parse!(
be_i128(&[0x00, 0x00, 0x00, 0x00, 0x00][..]),
Err(Err::Incomplete(Needed::new(11)))
);
assert_parse!(
be_i128(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
Err(Err::Incomplete(Needed::new(10)))
@ -1136,11 +1220,16 @@ mod tests {
Err(Err::Incomplete(Needed::new(3)))
);
assert_parse!(
be_i128(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
be_i128(
&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]
),
Err(Err::Incomplete(Needed::new(2)))
);
assert_parse!(
be_i128(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
be_i128(
&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
[..]
),
Err(Err::Incomplete(Needed::new(1)))
);
}
@ -1165,32 +1254,50 @@ mod tests {
fn le_u24_tests() {
assert_parse!(le_u24(&[0x00, 0x00, 0x00][..]), Ok((&b""[..], 0)));
assert_parse!(le_u24(&[0xFF, 0xFF, 0x00][..]), Ok((&b""[..], 65_535_u32)));
assert_parse!(le_u24(&[0x56, 0x34, 0x12][..]), Ok((&b""[..], 1_193_046_u32)));
assert_parse!(
le_u24(&[0x56, 0x34, 0x12][..]),
Ok((&b""[..], 1_193_046_u32))
);
}
#[test]
fn le_i24_tests() {
assert_parse!(le_i24(&[0xFF, 0xFF, 0xFF][..]), Ok((&b""[..], -1_i32)));
assert_parse!(le_i24(&[0x00, 0x00, 0xFF][..]), Ok((&b""[..], -65_536_i32)));
assert_parse!(le_i24(&[0xAA, 0xCB, 0xED][..]), Ok((&b""[..], -1_193_046_i32)));
assert_parse!(
le_i24(&[0xAA, 0xCB, 0xED][..]),
Ok((&b""[..], -1_193_046_i32))
);
}
#[test]
fn le_i32_tests() {
assert_parse!(le_i32(&[0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 0)));
assert_parse!(le_i32(&[0xff, 0xff, 0xff, 0x7f][..]), Ok((&b""[..], 2_147_483_647_i32)));
assert_parse!(
le_i32(&[0xff, 0xff, 0xff, 0x7f][..]),
Ok((&b""[..], 2_147_483_647_i32))
);
assert_parse!(le_i32(&[0xff, 0xff, 0xff, 0xff][..]), Ok((&b""[..], -1)));
assert_parse!(le_i32(&[0x00, 0x00, 0x00, 0x80][..]), Ok((&b""[..], -2_147_483_648_i32)));
assert_parse!(
le_i32(&[0x00, 0x00, 0x00, 0x80][..]),
Ok((&b""[..], -2_147_483_648_i32))
);
}
#[test]
fn le_i64_tests() {
assert_parse!(le_i64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 0)));
assert_parse!(
le_i64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
Ok((&b""[..], 0))
);
assert_parse!(
le_i64(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f][..]),
Ok((&b""[..], 9_223_372_036_854_775_807_i64))
);
assert_parse!(le_i64(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff][..]), Ok((&b""[..], -1)));
assert_parse!(
le_i64(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff][..]),
Ok((&b""[..], -1))
);
assert_parse!(
le_i64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80][..]),
Ok((&b""[..], -9_223_372_036_854_775_808_i64))
@ -1201,32 +1308,64 @@ mod tests {
#[cfg(stable_i128)]
fn le_i128_tests() {
assert_parse!(
le_i128(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
le_i128(
&[
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00
][..]
),
Ok((&b""[..], 0))
);
assert_parse!(
le_i128(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f][..]),
Ok((&b""[..], 170_141_183_460_469_231_731_687_303_715_884_105_727_i128))
le_i128(
&[
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x7f
][..]
),
Ok((
&b""[..],
170_141_183_460_469_231_731_687_303_715_884_105_727_i128
))
);
assert_parse!(
le_i128(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff][..]),
le_i128(
&[
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff
][..]
),
Ok((&b""[..], -1))
);
assert_parse!(
le_i128(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80][..]),
Ok((&b""[..], -170_141_183_460_469_231_731_687_303_715_884_105_728_i128))
le_i128(
&[
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80
][..]
),
Ok((
&b""[..],
-170_141_183_460_469_231_731_687_303_715_884_105_728_i128
))
);
}
#[test]
fn be_f32_tests() {
assert_parse!(be_f32(&[0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 0_f32)));
assert_parse!(be_f32(&[0x4d, 0x31, 0x1f, 0xd8][..]), Ok((&b""[..], 185_728_392_f32)));
assert_parse!(
be_f32(&[0x4d, 0x31, 0x1f, 0xd8][..]),
Ok((&b""[..], 185_728_392_f32))
);
}
#[test]
fn be_f64_tests() {
assert_parse!(be_f64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 0_f64)));
assert_parse!(
be_f64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
Ok((&b""[..], 0_f64))
);
assert_parse!(
be_f64(&[0x41, 0xa6, 0x23, 0xfb, 0x10, 0x00, 0x00, 0x00][..]),
Ok((&b""[..], 185_728_392_f64))
@ -1236,12 +1375,18 @@ mod tests {
#[test]
fn le_f32_tests() {
assert_parse!(le_f32(&[0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 0_f32)));
assert_parse!(le_f32(&[0xd8, 0x1f, 0x31, 0x4d][..]), Ok((&b""[..], 185_728_392_f32)));
assert_parse!(
le_f32(&[0xd8, 0x1f, 0x31, 0x4d][..]),
Ok((&b""[..], 185_728_392_f32))
);
}
#[test]
fn le_f64_tests() {
assert_parse!(le_f64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 0_f64)));
assert_parse!(
le_f64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
Ok((&b""[..], 0_f64))
);
assert_parse!(
le_f64(&[0x00, 0x00, 0x00, 0x10, 0xfb, 0x23, 0xa6, 0x41][..]),
Ok((&b""[..], 185_728_392_f64))
@ -1250,13 +1395,19 @@ mod tests {
#[test]
fn hex_u32_tests() {
assert_parse!(hex_u32(&b";"[..]), Err(Err::Error(error_position!(&b";"[..], ErrorKind::IsA))));
assert_parse!(
hex_u32(&b";"[..]),
Err(Err::Error(error_position!(&b";"[..], ErrorKind::IsA)))
);
assert_parse!(hex_u32(&b"ff;"[..]), Ok((&b";"[..], 255)));
assert_parse!(hex_u32(&b"1be2;"[..]), Ok((&b";"[..], 7138)));
assert_parse!(hex_u32(&b"c5a31be2;"[..]), Ok((&b";"[..], 3_315_801_058)));
assert_parse!(hex_u32(&b"C5A31be2;"[..]), Ok((&b";"[..], 3_315_801_058)));
assert_parse!(hex_u32(&b"00c5a31be2;"[..]), Ok((&b"e2;"[..], 12_952_347)));
assert_parse!(hex_u32(&b"c5a31be201;"[..]), Ok((&b"01;"[..], 3_315_801_058)));
assert_parse!(
hex_u32(&b"c5a31be201;"[..]),
Ok((&b"01;"[..], 3_315_801_058))
);
assert_parse!(hex_u32(&b"ffffffff;"[..]), Ok((&b";"[..], 4_294_967_295)));
assert_parse!(hex_u32(&b"0x1be2;"[..]), Ok((&b"x1be2;"[..], 0)));
assert_parse!(hex_u32(&b"12af"[..]), Err(Err::Incomplete(Needed::new(1))));
@ -1301,6 +1452,9 @@ mod tests {
}
let remaining_exponent = "-1.234E-";
assert_parse!(recognize_float(remaining_exponent), Err(Err::Incomplete(Needed::new(1))));
assert_parse!(
recognize_float(remaining_exponent),
Err(Err::Incomplete(Needed::new(1)))
);
}
}

View File

@ -130,7 +130,13 @@ mod tests {
fn re_match() {
named!(rm<&str,&str>, re_match!(r"^\d{4}-\d{2}-\d{2}"));
assert_eq!(rm("2015-09-07"), Ok(("", "2015-09-07")));
assert_eq!(rm("blah"), Err(Err::Error(error_position!(&"blah"[..], ErrorKind::RegexpMatch),)));
assert_eq!(
rm("blah"),
Err(Err::Error(error_position!(
&"blah"[..],
ErrorKind::RegexpMatch
),))
);
assert_eq!(rm("2015-09-07blah"), Ok(("", "2015-09-07blah")));
}
@ -138,7 +144,13 @@ mod tests {
fn re_find() {
named!(rm<&str,&str>, re_find!(r"^\d{4}-\d{2}-\d{2}"));
assert_eq!(rm("2015-09-07"), Ok(("", "2015-09-07")));
assert_eq!(rm("blah"), Err(Err::Error(error_position!(&"blah"[..], ErrorKind::RegexpFind),)));
assert_eq!(
rm("blah"),
Err(Err::Error(error_position!(
&"blah"[..],
ErrorKind::RegexpFind
),))
);
assert_eq!(rm("2015-09-07blah"), Ok(("blah", "2015-09-07")));
}
@ -147,7 +159,13 @@ mod tests {
fn re_matches() {
named!(rm< &str,Vec<&str> >, re_matches!(r"\d{4}-\d{2}-\d{2}"));
assert_eq!(rm("2015-09-07"), Ok(("", vec!["2015-09-07"])));
assert_eq!(rm("blah"), Err(Err::Error(error_position!(&"blah"[..], ErrorKind::RegexpMatches))));
assert_eq!(
rm("blah"),
Err(Err::Error(error_position!(
&"blah"[..],
ErrorKind::RegexpMatches
)))
);
assert_eq!(
rm("aaa2015-09-07blah2015-09-09pouet"),
Ok(("pouet", vec!["2015-09-07", "2015-09-09"]))
@ -162,10 +180,19 @@ mod tests {
rm("blah nom 0.3.11pouet"),
Ok(("pouet", vec!["nom 0.3.11", "nom", "0.3.11", "0", "3", "11"]))
);
assert_eq!(rm("blah"), Err(Err::Error(error_position!(&"blah"[..], ErrorKind::RegexpCapture))));
assert_eq!(
rm("blah"),
Err(Err::Error(error_position!(
&"blah"[..],
ErrorKind::RegexpCapture
)))
);
assert_eq!(
rm("hello nom 0.3.11 world regex 0.1.41"),
Ok((" world regex 0.1.41", vec!["nom 0.3.11", "nom", "0.3.11", "0", "3", "11"]))
Ok((
" world regex 0.1.41",
vec!["nom 0.3.11", "nom", "0.3.11", "0", "3", "11"]
))
);
}
@ -175,9 +202,18 @@ mod tests {
named!(rm< &str,Vec<Vec<&str>> >, re_captures!(r"([[:alpha:]]+)\s+((\d+).(\d+).(\d+))"));
assert_eq!(
rm("blah nom 0.3.11pouet"),
Ok(("pouet", vec![vec!["nom 0.3.11", "nom", "0.3.11", "0", "3", "11"]]))
Ok((
"pouet",
vec![vec!["nom 0.3.11", "nom", "0.3.11", "0", "3", "11"]]
))
);
assert_eq!(
rm("blah"),
Err(Err::Error(error_position!(
&"blah"[..],
ErrorKind::RegexpCapture
)))
);
assert_eq!(rm("blah"), Err(Err::Error(error_position!(&"blah"[..], ErrorKind::RegexpCapture))));
assert_eq!(
rm("hello nom 0.3.11 world regex 0.1.41 aaa"),
Ok((
@ -196,9 +232,15 @@ mod tests {
assert_eq!(rm(&b"2015-09-07"[..]), Ok((&b""[..], &b"2015-09-07"[..])));
assert_eq!(
rm(&b"blah"[..]),
Err(Err::Error(error_position!(&b"blah"[..], ErrorKind::RegexpMatch)))
Err(Err::Error(error_position!(
&b"blah"[..],
ErrorKind::RegexpMatch
)))
);
assert_eq!(
rm(&b"2015-09-07blah"[..]),
Ok((&b""[..], &b"2015-09-07blah"[..]))
);
assert_eq!(rm(&b"2015-09-07blah"[..]), Ok((&b""[..], &b"2015-09-07blah"[..])));
}
#[test]
@ -207,19 +249,31 @@ mod tests {
assert_eq!(rm(&b"2015-09-07"[..]), Ok((&b""[..], &b"2015-09-07"[..])));
assert_eq!(
rm(&b"blah"[..]),
Err(Err::Error(error_position!(&b"blah"[..], ErrorKind::RegexpFind)))
Err(Err::Error(error_position!(
&b"blah"[..],
ErrorKind::RegexpFind
)))
);
assert_eq!(
rm(&b"2015-09-07blah"[..]),
Ok((&b"blah"[..], &b"2015-09-07"[..]))
);
assert_eq!(rm(&b"2015-09-07blah"[..]), Ok((&b"blah"[..], &b"2015-09-07"[..])));
}
#[cfg(feature = "alloc")]
#[test]
fn re_bytes_matches() {
named!(rm<Vec<&[u8]>>, re_bytes_matches!(r"\d{4}-\d{2}-\d{2}"));
assert_eq!(rm(&b"2015-09-07"[..]), Ok((&b""[..], vec![&b"2015-09-07"[..]])));
assert_eq!(
rm(&b"2015-09-07"[..]),
Ok((&b""[..], vec![&b"2015-09-07"[..]]))
);
assert_eq!(
rm(&b"blah"[..]),
Err(Err::Error(error_position!(&b"blah"[..], ErrorKind::RegexpMatches)))
Err(Err::Error(error_position!(
&b"blah"[..],
ErrorKind::RegexpMatches
)))
);
assert_eq!(
rm(&b"aaa2015-09-07blah2015-09-09pouet"[..]),
@ -230,23 +284,43 @@ mod tests {
#[cfg(feature = "alloc")]
#[test]
fn re_bytes_capture() {
named!(rm<Vec<&[u8]>>, re_bytes_capture!(r"([[:alpha:]]+)\s+((\d+).(\d+).(\d+))"));
named!(
rm<Vec<&[u8]>>,
re_bytes_capture!(r"([[:alpha:]]+)\s+((\d+).(\d+).(\d+))")
);
assert_eq!(
rm(&b"blah nom 0.3.11pouet"[..]),
Ok((
&b"pouet"[..],
vec![&b"nom 0.3.11"[..], &b"nom"[..], &b"0.3.11"[..], &b"0"[..], &b"3"[..], &b"11"[..],]
vec![
&b"nom 0.3.11"[..],
&b"nom"[..],
&b"0.3.11"[..],
&b"0"[..],
&b"3"[..],
&b"11"[..],
]
))
);
assert_eq!(
rm(&b"blah"[..]),
Err(Err::Error(error_position!(&b"blah"[..], ErrorKind::RegexpCapture)))
Err(Err::Error(error_position!(
&b"blah"[..],
ErrorKind::RegexpCapture
)))
);
assert_eq!(
rm(&b"hello nom 0.3.11 world regex 0.1.41"[..]),
Ok((
&b" world regex 0.1.41"[..],
vec![&b"nom 0.3.11"[..], &b"nom"[..], &b"0.3.11"[..], &b"0"[..], &b"3"[..], &b"11"[..],]
vec![
&b"nom 0.3.11"[..],
&b"nom"[..],
&b"0.3.11"[..],
&b"0"[..],
&b"3"[..],
&b"11"[..],
]
))
);
}
@ -254,7 +328,10 @@ mod tests {
#[cfg(feature = "alloc")]
#[test]
fn re_bytes_captures() {
named!(rm<Vec<Vec<&[u8]>>>, re_bytes_captures!(r"([[:alpha:]]+)\s+((\d+).(\d+).(\d+))"));
named!(
rm<Vec<Vec<&[u8]>>>,
re_bytes_captures!(r"([[:alpha:]]+)\s+((\d+).(\d+).(\d+))")
);
assert_eq!(
rm(&b"blah nom 0.3.11pouet"[..]),
Ok((
@ -271,14 +348,24 @@ mod tests {
);
assert_eq!(
rm(&b"blah"[..]),
Err(Err::Error(error_position!(&b"blah"[..], ErrorKind::RegexpCapture)))
Err(Err::Error(error_position!(
&b"blah"[..],
ErrorKind::RegexpCapture
)))
);
assert_eq!(
rm(&b"hello nom 0.3.11 world regex 0.1.41 aaa"[..]),
Ok((
&b" aaa"[..],
vec![
vec![&b"nom 0.3.11"[..], &b"nom"[..], &b"0.3.11"[..], &b"0"[..], &b"3"[..], &b"11"[..],],
vec![
&b"nom 0.3.11"[..],
&b"nom"[..],
&b"0.3.11"[..],
&b"0"[..],
&b"3"[..],
&b"11"[..],
],
vec![
&b"regex 0.1.41"[..],
&b"regex"[..],

View File

@ -61,7 +61,10 @@ pub mod str {
E: ParseError<&'a str>,
{
move |i| {
let v: Vec<_> = re.find_iter(i).map(|m| i.slice(m.start()..m.end())).collect();
let v: Vec<_> = re
.find_iter(i)
.map(|m| i.slice(m.start()..m.end()))
.collect();
if !v.is_empty() {
let offset = {
let end = v.last().unwrap();
@ -208,7 +211,10 @@ pub mod str {
let re = Regex::new(r"^\d{4}-\d{2}-\d{2}").unwrap();
let rm = re_match(re);
assert_parse!(rm("2015-09-07"), Ok(("", "2015-09-07")));
assert_eq!(rm("blah"), Err(Err::Error((&"blah"[..], ErrorKind::RegexpMatch))));
assert_eq!(
rm("blah"),
Err(Err::Error((&"blah"[..], ErrorKind::RegexpMatch)))
);
assert_eq!(rm("2015-09-07blah"), Ok(("", "2015-09-07blah")));
}
@ -217,7 +223,10 @@ pub mod str {
let re = Regex::new(r"^\d{4}-\d{2}-\d{2}").unwrap();
let rm = re_find(re);
assert_parse!(rm("2015-09-07"), Ok(("", "2015-09-07")));
assert_eq!(rm("blah"), Err(Err::Error((&"blah"[..], ErrorKind::RegexpFind))));
assert_eq!(
rm("blah"),
Err(Err::Error((&"blah"[..], ErrorKind::RegexpFind)))
);
assert_eq!(rm("2015-09-07blah"), Ok(("blah", "2015-09-07")));
}
@ -227,7 +236,10 @@ pub mod str {
let re = Regex::new(r"\d{4}-\d{2}-\d{2}").unwrap();
let rm = re_matches(re);
assert_parse!(rm("2015-09-07"), Ok(("", vec!["2015-09-07"])));
assert_eq!(rm("blah"), Err(Err::Error((&"blah"[..], ErrorKind::RegexpMatches))));
assert_eq!(
rm("blah"),
Err(Err::Error((&"blah"[..], ErrorKind::RegexpMatches)))
);
assert_eq!(
rm("aaa2015-09-07blah2015-09-09pouet"),
Ok(("pouet", vec!["2015-09-07", "2015-09-09"]))
@ -243,10 +255,16 @@ pub mod str {
rm("blah nom 0.3.11pouet"),
Ok(("pouet", vec!["nom 0.3.11", "nom", "0.3.11", "0", "3", "11"]))
);
assert_eq!(rm("blah"), Err(Err::Error(("blah", ErrorKind::RegexpCapture))));
assert_eq!(
rm("blah"),
Err(Err::Error(("blah", ErrorKind::RegexpCapture)))
);
assert_eq!(
rm("hello nom 0.3.11 world regex 0.1.41"),
Ok((" world regex 0.1.41", vec!["nom 0.3.11", "nom", "0.3.11", "0", "3", "11"]))
Ok((
" world regex 0.1.41",
vec!["nom 0.3.11", "nom", "0.3.11", "0", "3", "11"]
))
);
}
@ -257,9 +275,15 @@ pub mod str {
let rm = re_captures(re);
assert_parse!(
rm("blah nom 0.3.11pouet"),
Ok(("pouet", vec![vec!["nom 0.3.11", "nom", "0.3.11", "0", "3", "11"]]))
Ok((
"pouet",
vec![vec!["nom 0.3.11", "nom", "0.3.11", "0", "3", "11"]]
))
);
assert_eq!(
rm("blah"),
Err(Err::Error((&"blah"[..], ErrorKind::RegexpCapture)))
);
assert_eq!(rm("blah"), Err(Err::Error((&"blah"[..], ErrorKind::RegexpCapture))));
assert_eq!(
rm("hello nom 0.3.11 world regex 0.1.41 aaa"),
Ok((
@ -333,7 +357,10 @@ pub mod bytes {
E: ParseError<&'a [u8]>,
{
move |i| {
let v: Vec<_> = re.find_iter(i).map(|m| i.slice(m.start()..m.end())).collect();
let v: Vec<_> = re
.find_iter(i)
.map(|m| i.slice(m.start()..m.end()))
.collect();
if !v.is_empty() {
let offset = {
let end = v.last().unwrap();
@ -434,7 +461,9 @@ pub mod bytes {
/// # }
/// ```
#[cfg(feature = "regexp")]
pub fn re_captures<'a, E>(re: Regex) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], Vec<Vec<&'a [u8]>>, E>
pub fn re_captures<'a, E>(
re: Regex,
) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], Vec<Vec<&'a [u8]>>, E>
where
E: ParseError<&'a [u8]>,
{
@ -480,8 +509,14 @@ pub mod bytes {
let re = Regex::new(r"^\d{4}-\d{2}-\d{2}").unwrap();
let rm = re_match(re);
assert_parse!(rm(&b"2015-09-07"[..]), Ok((&b""[..], &b"2015-09-07"[..])));
assert_eq!(rm(&b"blah"[..]), Err(Err::Error((&b"blah"[..], ErrorKind::RegexpMatch))));
assert_eq!(rm(&b"2015-09-07blah"[..]), Ok((&b""[..], &b"2015-09-07blah"[..])));
assert_eq!(
rm(&b"blah"[..]),
Err(Err::Error((&b"blah"[..], ErrorKind::RegexpMatch)))
);
assert_eq!(
rm(&b"2015-09-07blah"[..]),
Ok((&b""[..], &b"2015-09-07blah"[..]))
);
}
#[test]
@ -489,8 +524,14 @@ pub mod bytes {
let re = Regex::new(r"^\d{4}-\d{2}-\d{2}").unwrap();
let rm = re_find(re);
assert_parse!(rm(&b"2015-09-07"[..]), Ok((&b""[..], &b"2015-09-07"[..])));
assert_eq!(rm(&b"blah"[..]), Err(Err::Error((&b"blah"[..], ErrorKind::RegexpFind))));
assert_eq!(rm(&b"2015-09-07blah"[..]), Ok((&b"blah"[..], &b"2015-09-07"[..])));
assert_eq!(
rm(&b"blah"[..]),
Err(Err::Error((&b"blah"[..], ErrorKind::RegexpFind)))
);
assert_eq!(
rm(&b"2015-09-07blah"[..]),
Ok((&b"blah"[..], &b"2015-09-07"[..]))
);
}
#[cfg(feature = "alloc")]
@ -498,8 +539,14 @@ pub mod bytes {
fn re_matches_bytes() {
let re = Regex::new(r"\d{4}-\d{2}-\d{2}").unwrap();
let rm = re_matches(re);
assert_parse!(rm(&b"2015-09-07"[..]), Ok((&b""[..], vec![&b"2015-09-07"[..]])));
assert_eq!(rm(&b"blah"[..]), Err(Err::Error((&b"blah"[..], ErrorKind::RegexpMatches))));
assert_parse!(
rm(&b"2015-09-07"[..]),
Ok((&b""[..], vec![&b"2015-09-07"[..]]))
);
assert_eq!(
rm(&b"blah"[..]),
Err(Err::Error((&b"blah"[..], ErrorKind::RegexpMatches)))
);
assert_eq!(
rm(&b"aaa2015-09-07blah2015-09-09pouet"[..]),
Ok((&b"pouet"[..], vec![&b"2015-09-07"[..], &b"2015-09-09"[..]]))
@ -515,15 +562,32 @@ pub mod bytes {
rm(&b"blah nom 0.3.11pouet"[..]),
Ok((
&b"pouet"[..],
vec![&b"nom 0.3.11"[..], &b"nom"[..], &b"0.3.11"[..], &b"0"[..], &b"3"[..], &b"11"[..]]
vec![
&b"nom 0.3.11"[..],
&b"nom"[..],
&b"0.3.11"[..],
&b"0"[..],
&b"3"[..],
&b"11"[..]
]
))
);
assert_eq!(rm(&b"blah"[..]), Err(Err::Error((&b"blah"[..], ErrorKind::RegexpCapture))));
assert_eq!(
rm(&b"blah"[..]),
Err(Err::Error((&b"blah"[..], ErrorKind::RegexpCapture)))
);
assert_eq!(
rm(&b"hello nom 0.3.11 world regex 0.1.41"[..]),
Ok((
&b" world regex 0.1.41"[..],
vec![&b"nom 0.3.11"[..], &b"nom"[..], &b"0.3.11"[..], &b"0"[..], &b"3"[..], &b"11"[..]]
vec![
&b"nom 0.3.11"[..],
&b"nom"[..],
&b"0.3.11"[..],
&b"0"[..],
&b"3"[..],
&b"11"[..]
]
))
);
}
@ -548,13 +612,23 @@ pub mod bytes {
))
);
assert_eq!(rm(&b"blah"[..]), Err(Err::Error((&b"blah"[..], ErrorKind::RegexpCapture))));
assert_eq!(
rm(&b"blah"[..]),
Err(Err::Error((&b"blah"[..], ErrorKind::RegexpCapture)))
);
assert_eq!(
rm(&b"hello nom 0.3.11 world regex 0.1.41 aaa"[..]),
Ok((
&b" aaa"[..],
vec![
vec![&b"nom 0.3.11"[..], &b"nom"[..], &b"0.3.11"[..], &b"0"[..], &b"3"[..], &b"11"[..]],
vec![
&b"nom 0.3.11"[..],
&b"nom"[..],
&b"0.3.11"[..],
&b"0"[..],
&b"3"[..],
&b"11"[..]
],
vec![
&b"regex 0.1.41"[..],
&b"regex"[..],

View File

@ -473,9 +473,9 @@ macro_rules! nom_compile_error (
#[cfg(test)]
mod tests {
use crate::error::ErrorKind;
use crate::internal::{Err, IResult, Needed};
use crate::number::streaming::be_u16;
use crate::error::ErrorKind;
// reproduce the tag and take macros, because of module import order
macro_rules! tag (
@ -645,9 +645,18 @@ mod tests {
named!(tag_def, tag!("def"));
named!( pair_abc_def<&[u8],(&[u8], &[u8])>, pair!(tag_abc, tag_def) );
assert_eq!(pair_abc_def(&b"abcdefghijkl"[..]), Ok((&b"ghijkl"[..], (&b"abc"[..], &b"def"[..]))));
assert_eq!(pair_abc_def(&b"ab"[..]), Err(Err::Incomplete(Needed::new(3))));
assert_eq!(pair_abc_def(&b"abcd"[..]), Err(Err::Incomplete(Needed::new(3))));
assert_eq!(
pair_abc_def(&b"abcdefghijkl"[..]),
Ok((&b"ghijkl"[..], (&b"abc"[..], &b"def"[..])))
);
assert_eq!(
pair_abc_def(&b"ab"[..]),
Err(Err::Incomplete(Needed::new(3)))
);
assert_eq!(
pair_abc_def(&b"abcd"[..]),
Err(Err::Incomplete(Needed::new(3)))
);
assert_eq!(
pair_abc_def(&b"xxx"[..]),
Err(Err::Error(error_position!(&b"xxx"[..], ErrorKind::Tag)))
@ -673,8 +682,14 @@ mod tests {
sep_pair_abc_def(&b"abc,defghijkl"[..]),
Ok((&b"ghijkl"[..], (&b"abc"[..], &b"def"[..])))
);
assert_eq!(sep_pair_abc_def(&b"ab"[..]), Err(Err::Incomplete(Needed::new(3))));
assert_eq!(sep_pair_abc_def(&b"abc,d"[..]), Err(Err::Incomplete(Needed::new(3))));
assert_eq!(
sep_pair_abc_def(&b"ab"[..]),
Err(Err::Incomplete(Needed::new(3)))
);
assert_eq!(
sep_pair_abc_def(&b"abc,d"[..]),
Err(Err::Incomplete(Needed::new(3)))
);
assert_eq!(
sep_pair_abc_def(&b"xxx"[..]),
Err(Err::Error(error_position!(&b"xxx"[..], ErrorKind::Tag)))
@ -695,9 +710,18 @@ mod tests {
named!(tag_efgh, tag!("efgh"));
named!( preceded_abcd_efgh<&[u8], &[u8]>, preceded!(tag_abcd, tag_efgh) );
assert_eq!(preceded_abcd_efgh(&b"abcdefghijkl"[..]), Ok((&b"ijkl"[..], &b"efgh"[..])));
assert_eq!(preceded_abcd_efgh(&b"ab"[..]), Err(Err::Incomplete(Needed::new(4))));
assert_eq!(preceded_abcd_efgh(&b"abcde"[..]), Err(Err::Incomplete(Needed::new(4))));
assert_eq!(
preceded_abcd_efgh(&b"abcdefghijkl"[..]),
Ok((&b"ijkl"[..], &b"efgh"[..]))
);
assert_eq!(
preceded_abcd_efgh(&b"ab"[..]),
Err(Err::Incomplete(Needed::new(4)))
);
assert_eq!(
preceded_abcd_efgh(&b"abcde"[..]),
Err(Err::Incomplete(Needed::new(4)))
);
assert_eq!(
preceded_abcd_efgh(&b"xxx"[..]),
Err(Err::Error(error_position!(&b"xxx"[..], ErrorKind::Tag)))
@ -718,9 +742,18 @@ mod tests {
named!(tag_efgh, tag!("efgh"));
named!( terminated_abcd_efgh<&[u8], &[u8]>, terminated!(tag_abcd, tag_efgh) );
assert_eq!(terminated_abcd_efgh(&b"abcdefghijkl"[..]), Ok((&b"ijkl"[..], &b"abcd"[..])));
assert_eq!(terminated_abcd_efgh(&b"ab"[..]), Err(Err::Incomplete(Needed::new(4))));
assert_eq!(terminated_abcd_efgh(&b"abcde"[..]), Err(Err::Incomplete(Needed::new(4))));
assert_eq!(
terminated_abcd_efgh(&b"abcdefghijkl"[..]),
Ok((&b"ijkl"[..], &b"abcd"[..]))
);
assert_eq!(
terminated_abcd_efgh(&b"ab"[..]),
Err(Err::Incomplete(Needed::new(4)))
);
assert_eq!(
terminated_abcd_efgh(&b"abcde"[..]),
Err(Err::Incomplete(Needed::new(4)))
);
assert_eq!(
terminated_abcd_efgh(&b"xxx"[..]),
Err(Err::Error(error_position!(&b"xxx"[..], ErrorKind::Tag)))
@ -742,17 +775,32 @@ mod tests {
named!(tag_ghi, tag!("ghi"));
named!( delimited_abc_def_ghi<&[u8], &[u8]>, delimited!(tag_abc, tag_def, tag_ghi) );
assert_eq!(delimited_abc_def_ghi(&b"abcdefghijkl"[..]), Ok((&b"jkl"[..], &b"def"[..])));
assert_eq!(delimited_abc_def_ghi(&b"ab"[..]), Err(Err::Incomplete(Needed::new(3))));
assert_eq!(delimited_abc_def_ghi(&b"abcde"[..]), Err(Err::Incomplete(Needed::new(3))));
assert_eq!(delimited_abc_def_ghi(&b"abcdefgh"[..]), Err(Err::Incomplete(Needed::new(3))));
assert_eq!(
delimited_abc_def_ghi(&b"abcdefghijkl"[..]),
Ok((&b"jkl"[..], &b"def"[..]))
);
assert_eq!(
delimited_abc_def_ghi(&b"ab"[..]),
Err(Err::Incomplete(Needed::new(3)))
);
assert_eq!(
delimited_abc_def_ghi(&b"abcde"[..]),
Err(Err::Incomplete(Needed::new(3)))
);
assert_eq!(
delimited_abc_def_ghi(&b"abcdefgh"[..]),
Err(Err::Incomplete(Needed::new(3)))
);
assert_eq!(
delimited_abc_def_ghi(&b"xxx"[..]),
Err(Err::Error(error_position!(&b"xxx"[..], ErrorKind::Tag)))
);
assert_eq!(
delimited_abc_def_ghi(&b"xxxdefghi"[..]),
Err(Err::Error(error_position!(&b"xxxdefghi"[..], ErrorKind::Tag),))
Err(Err::Error(error_position!(
&b"xxxdefghi"[..],
ErrorKind::Tag
),))
);
assert_eq!(
delimited_abc_def_ghi(&b"abcxxxghi"[..]),
@ -769,7 +817,10 @@ mod tests {
named!(tuple_3<&[u8], (u16, &[u8], &[u8]) >,
tuple!( be_u16 , take!(3), tag!("fg") ) );
assert_eq!(tuple_3(&b"abcdefgh"[..]), Ok((&b"h"[..], (0x6162u16, &b"cde"[..], &b"fg"[..]))));
assert_eq!(
tuple_3(&b"abcdefgh"[..]),
Ok((&b"h"[..], (0x6162u16, &b"cde"[..], &b"fg"[..])))
);
assert_eq!(tuple_3(&b"abcd"[..]), Err(Err::Incomplete(Needed::new(3))));
assert_eq!(tuple_3(&b"abcde"[..]), Err(Err::Incomplete(Needed::new(2))));
assert_eq!(
@ -807,10 +858,19 @@ mod tests {
//trace_macros!(false);
assert_eq!(do_parser(&b"abcdabcdefghefghX"[..]), Ok((&b"X"[..], (1, 2))));
assert_eq!(
do_parser(&b"abcdabcdefghefghX"[..]),
Ok((&b"X"[..], (1, 2)))
);
assert_eq!(do_parser(&b"abcdefghefghX"[..]), Ok((&b"X"[..], (1, 2))));
assert_eq!(do_parser(&b"abcdab"[..]), Err(Err::Incomplete(Needed::new(4))));
assert_eq!(do_parser(&b"abcdefghef"[..]), Err(Err::Incomplete(Needed::new(4))));
assert_eq!(
do_parser(&b"abcdab"[..]),
Err(Err::Incomplete(Needed::new(4)))
);
assert_eq!(
do_parser(&b"abcdefghef"[..]),
Err(Err::Incomplete(Needed::new(4)))
);
}
#[cfg_attr(rustfmt, rustfmt_skip)]

View File

@ -3,8 +3,8 @@
#[macro_use]
mod macros;
use crate::internal::{IResult, Parser};
use crate::error::ParseError;
use crate::internal::{IResult, Parser};
/// Gets an object from the first parser,
/// then gets another object from the second parser.
@ -25,7 +25,10 @@ use crate::error::ParseError;
/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
/// ```
pub fn pair<I, O1, O2, E: ParseError<I>, F, G>(mut first: F, mut second: G) -> impl FnMut(I) -> IResult<I, (O1, O2), E>
pub fn pair<I, O1, O2, E: ParseError<I>, F, G>(
mut first: F,
mut second: G,
) -> impl FnMut(I) -> IResult<I, (O1, O2), E>
where
F: Parser<I, O1, E>,
G: Parser<I, O2, E>,
@ -38,7 +41,11 @@ where
// this implementation is used for type inference issues in macros
#[doc(hidden)]
pub fn pairc<I, O1, O2, E: ParseError<I>, F, G>(input: I, first: F, second: G) -> IResult<I, (O1, O2), E>
pub fn pairc<I, O1, O2, E: ParseError<I>, F, G>(
input: I,
first: F,
second: G,
) -> IResult<I, (O1, O2), E>
where
F: Fn(I) -> IResult<I, O1, E>,
G: Fn(I) -> IResult<I, O2, E>,
@ -65,7 +72,10 @@ where
/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
/// ```
pub fn preceded<I, O1, O2, E: ParseError<I>, F, G>(mut first: F, mut second: G) -> impl FnMut(I) -> IResult<I, O2, E>
pub fn preceded<I, O1, O2, E: ParseError<I>, F, G>(
mut first: F,
mut second: G,
) -> impl FnMut(I) -> IResult<I, O2, E>
where
F: Parser<I, O1, E>,
G: Parser<I, O2, E>,
@ -78,7 +88,11 @@ where
// this implementation is used for type inference issues in macros
#[doc(hidden)]
pub fn precededc<I, O1, O2, E: ParseError<I>, F, G>(input: I, first: F, second: G) -> IResult<I, O2, E>
pub fn precededc<I, O1, O2, E: ParseError<I>, F, G>(
input: I,
first: F,
second: G,
) -> IResult<I, O2, E>
where
F: Fn(I) -> IResult<I, O1, E>,
G: Fn(I) -> IResult<I, O2, E>,
@ -105,7 +119,10 @@ where
/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
/// ```
pub fn terminated<I, O1, O2, E: ParseError<I>, F, G>(mut first: F, mut second: G) -> impl FnMut(I) -> IResult<I, O1, E>
pub fn terminated<I, O1, O2, E: ParseError<I>, F, G>(
mut first: F,
mut second: G,
) -> impl FnMut(I) -> IResult<I, O1, E>
where
F: Parser<I, O1, E>,
G: Parser<I, O2, E>,
@ -118,7 +135,11 @@ where
// this implementation is used for type inference issues in macros
#[doc(hidden)]
pub fn terminatedc<I, O1, O2, E: ParseError<I>, F, G>(input: I, first: F, second: G) -> IResult<I, O1, E>
pub fn terminatedc<I, O1, O2, E: ParseError<I>, F, G>(
input: I,
first: F,
second: G,
) -> IResult<I, O1, E>
where
F: Fn(I) -> IResult<I, O1, E>,
G: Fn(I) -> IResult<I, O2, E>,
@ -147,7 +168,11 @@ where
/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
/// ```
pub fn separated_pair<I, O1, O2, O3, E: ParseError<I>, F, G, H>(mut first: F, mut sep: G, mut second: H) -> impl FnMut(I) -> IResult<I, (O1, O3), E>
pub fn separated_pair<I, O1, O2, O3, E: ParseError<I>, F, G, H>(
mut first: F,
mut sep: G,
mut second: H,
) -> impl FnMut(I) -> IResult<I, (O1, O3), E>
where
F: Parser<I, O1, E>,
G: Parser<I, O2, E>,
@ -162,7 +187,12 @@ where
// this implementation is used for type inference issues in macros
#[doc(hidden)]
pub fn separated_pairc<I, O1, O2, O3, E: ParseError<I>, F, G, H>(input: I, first: F, sep: G, second: H) -> IResult<I, (O1, O3), E>
pub fn separated_pairc<I, O1, O2, O3, E: ParseError<I>, F, G, H>(
input: I,
first: F,
sep: G,
second: H,
) -> IResult<I, (O1, O3), E>
where
F: Fn(I) -> IResult<I, O1, E>,
G: Fn(I) -> IResult<I, O2, E>,
@ -192,7 +222,11 @@ where
/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
/// ```
pub fn delimited<I, O1, O2, O3, E: ParseError<I>, F, G, H>(mut first: F, mut sep: G, mut second: H) -> impl FnMut(I) -> IResult<I, O2, E>
pub fn delimited<I, O1, O2, O3, E: ParseError<I>, F, G, H>(
mut first: F,
mut sep: G,
mut second: H,
) -> impl FnMut(I) -> IResult<I, O2, E>
where
F: Parser<I, O1, E>,
G: Parser<I, O2, E>,
@ -207,7 +241,12 @@ where
// this implementation is used for type inference issues in macros
#[doc(hidden)]
pub fn delimitedc<I, O1, O2, O3, E: ParseError<I>, F, G, H>(input: I, first: F, sep: G, second: H) -> IResult<I, O2, E>
pub fn delimitedc<I, O1, O2, O3, E: ParseError<I>, F, G, H>(
input: I,
first: F,
sep: G,
second: H,
) -> IResult<I, O2, E>
where
F: Fn(I) -> IResult<I, O1, E>,
G: Fn(I) -> IResult<I, O2, E>,
@ -219,15 +258,17 @@ where
/// helper trait for the tuple combinator
///
/// this trait is implemented for tuples of parsers of up to 21 elements
pub trait Tuple<I,O,E> {
pub trait Tuple<I, O, E> {
/// parses the input and returns a tuple of results of each parser
fn parse(&mut self, input: I) -> IResult<I,O,E>;
fn parse(&mut self, input: I) -> IResult<I, O, E>;
}
impl<Input, Output, Error: ParseError<Input>, F: Parser<Input, Output, Error> > Tuple<Input, (Output,), Error> for (F,) {
fn parse(&mut self, input: Input) -> IResult<Input,(Output,),Error> {
self.0.parse(input).map(|(i,o)| (i, (o,)))
}
impl<Input, Output, Error: ParseError<Input>, F: Parser<Input, Output, Error>>
Tuple<Input, (Output,), Error> for (F,)
{
fn parse(&mut self, input: Input) -> IResult<Input, (Output,), Error> {
self.0.parse(input).map(|(i, o)| (i, (o,)))
}
}
macro_rules! tuple_trait(
@ -291,10 +332,10 @@ tuple_trait!(FnA A, FnB B, FnC C, FnD D, FnE E, FnF F, FnG G, FnH H, FnI I, FnJ
/// assert_eq!(parser("abc123def"), Ok(("", ("abc", "123", "def"))));
/// assert_eq!(parser("123def"), Err(Err::Error(("123def", ErrorKind::Alpha))));
/// ```
pub fn tuple<I, O, E: ParseError<I>, List: Tuple<I,O,E>>(mut l: List) -> impl FnMut(I) -> IResult<I, O, E> {
move |i: I| {
l.parse(i)
}
pub fn tuple<I, O, E: ParseError<I>, List: Tuple<I, O, E>>(
mut l: List,
) -> impl FnMut(I) -> IResult<I, O, E> {
move |i: I| l.parse(i)
}
#[cfg(test)]
@ -304,10 +345,13 @@ mod tests {
#[test]
fn single_element_tuples() {
use crate::character::complete::{alpha1, digit1};
use crate::{Err, error::ErrorKind};
use crate::{error::ErrorKind, Err};
let mut parser = tuple((alpha1,));
assert_eq!(parser("abc123def"), Ok(("123def", ("abc",))));
assert_eq!(parser("123def"), Err(Err::Error(("123def", ErrorKind::Alpha))));
assert_eq!(
parser("123def"),
Err(Err::Error(("123def", ErrorKind::Alpha)))
);
}
}

View File

@ -1,6 +1,6 @@
#[cfg(test)]
mod test {
use crate::{Err, error::ErrorKind, IResult};
use crate::{error::ErrorKind, Err, IResult};
#[test]
fn tagtr_succeed() {
@ -12,10 +12,7 @@ mod test {
match test(INPUT) {
Ok((extra, output)) => {
assert!(
extra == " World!",
"Parser `tag` consumed leftover input."
);
assert!(extra == " World!", "Parser `tag` consumed leftover input.");
assert!(
output == TAG,
"Parser `tag` doesn't return the tag it matched on success. \
@ -37,7 +34,7 @@ mod test {
const INPUT: &str = "Hello";
const TAG: &str = "Hello World!";
let res: IResult<_,_,(_, ErrorKind)> = tag!(INPUT, TAG);
let res: IResult<_, _, (_, ErrorKind)> = tag!(INPUT, TAG);
match res {
Err(Err::Incomplete(_)) => (),
other => {
@ -55,7 +52,7 @@ mod test {
const INPUT: &str = "Hello World!";
const TAG: &str = "Random"; // TAG must be closer than INPUT.
let res: IResult<_,_,(_, ErrorKind)> = tag!(INPUT, TAG);
let res: IResult<_, _, (_, ErrorKind)> = tag!(INPUT, TAG);
match res {
Err(Err::Error(_)) => (),
other => {
@ -73,7 +70,7 @@ mod test {
const CONSUMED: &str = "βèƒôřèÂßÇ";
const LEFTOVER: &str = "áƒƭèř";
let res: IResult<_,_,(_, ErrorKind)> = take!(INPUT, 9);
let res: IResult<_, _, (_, ErrorKind)> = take!(INPUT, 9);
match res {
Ok((extra, output)) => {
assert!(
@ -103,7 +100,7 @@ mod test {
const CONSUMED: &str = "βèƒôřè";
const LEFTOVER: &str = "ÂßÇ∂áƒƭèř";
let res: IResult<_,_,(_, ErrorKind)> = take_until!(INPUT, FIND);
let res: IResult<_, _, (_, ErrorKind)> = take_until!(INPUT, FIND);
match res {
Ok((extra, output)) => {
assert!(
@ -132,7 +129,7 @@ mod test {
fn take_s_incomplete() {
const INPUT: &str = "βèƒôřèÂßÇá";
let res: IResult<_,_,(_, ErrorKind)> = take!(INPUT, 13);
let res: IResult<_, _, (_, ErrorKind)> = take!(INPUT, 13);
match res {
Err(Err::Incomplete(_)) => (),
other => panic!(
@ -283,7 +280,15 @@ mod test {
const CONSUMED: &str = "βèƒôřèÂßÇ";
const LEFTOVER: &str = "áƒƭèř";
fn while_s(c: char) -> bool {
c == 'β' || c == 'è' || c == 'ƒ' || c == 'ô' || c == 'ř' || c == 'è' || c == 'Â' || c == 'ß' || c == 'Ç'
c == 'β'
|| c == 'è'
|| c == 'ƒ'
|| c == 'ô'
|| c == 'ř'
|| c == 'è'
|| c == 'Â'
|| c == 'ß'
|| c == 'Ç'
}
fn test(input: &str) -> IResult<&str, &str> {
take_while!(input, while_s)
@ -332,7 +337,15 @@ mod test {
const CONSUMED: &str = "βèƒôřèÂßÇ";
const LEFTOVER: &str = "áƒƭèř";
fn while1_s(c: char) -> bool {
c == 'β' || c == 'è' || c == 'ƒ' || c == 'ô' || c == 'ř' || c == 'è' || c == 'Â' || c == 'ß' || c == 'Ç'
c == 'β'
|| c == 'è'
|| c == 'ƒ'
|| c == 'ô'
|| c == 'ř'
|| c == 'è'
|| c == 'Â'
|| c == 'ß'
|| c == 'Ç'
}
fn test(input: &str) -> IResult<&str, &str> {
take_while1!(input, while1_s)
@ -364,7 +377,7 @@ mod test {
const INPUT: &str = "βèƒôřè";
const FIND: &str = "βèƒôřèÂßÇ";
let res: IResult<_,_,(_, ErrorKind)> = take_until!(INPUT, FIND);
let res: IResult<_, _, (_, ErrorKind)> = take_until!(INPUT, FIND);
match res {
Err(Err::Incomplete(_)) => (),
other => panic!(
@ -446,7 +459,7 @@ mod test {
const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
const FIND: &str = "Ráñδô₥";
let res: IResult<_,_,(_, ErrorKind)> = take_until!(INPUT, FIND);
let res: IResult<_, _, (_, ErrorKind)> = take_until!(INPUT, FIND);
match res {
Err(Err::Incomplete(_)) => (),
other => panic!(
@ -472,8 +485,8 @@ mod test {
#[test]
fn utf8_indexing() {
named!(dot(&str) -> &str,
tag!(".")
);
tag!(".")
);
let _ = dot("");
}

View File

@ -1,15 +1,15 @@
//! Traits input types have to implement to work with nom combinators
//!
use crate::error::{ErrorKind, ParseError};
use crate::internal::{Err, IResult, Needed};
use crate::error::{ParseError, ErrorKind};
use crate::lib::std::ops::{Range, RangeFrom, RangeFull, RangeTo};
use crate::lib::std::iter::Enumerate;
use crate::lib::std::slice::Iter;
use crate::lib::std::iter::Map;
use crate::lib::std::str::Chars;
use crate::lib::std::str::CharIndices;
use crate::lib::std::str::FromStr;
use crate::lib::std::ops::{Range, RangeFrom, RangeFull, RangeTo};
use crate::lib::std::slice::Iter;
use crate::lib::std::str::from_utf8;
use crate::lib::std::str::CharIndices;
use crate::lib::std::str::Chars;
use crate::lib::std::str::FromStr;
use memchr;
#[cfg(feature = "alloc")]
@ -193,7 +193,9 @@ impl AsChar for u8 {
}
#[inline]
fn is_hex_digit(self) -> bool {
(self >= 0x30 && self <= 0x39) || (self >= 0x41 && self <= 0x46) || (self >= 0x61 && self <= 0x66)
(self >= 0x30 && self <= 0x39)
|| (self >= 0x41 && self <= 0x46)
|| (self >= 0x61 && self <= 0x66)
}
#[inline]
fn is_oct_digit(self) -> bool {
@ -223,7 +225,9 @@ impl<'a> AsChar for &'a u8 {
}
#[inline]
fn is_hex_digit(self) -> bool {
(*self >= 0x30 && *self <= 0x39) || (*self >= 0x41 && *self <= 0x46) || (*self >= 0x61 && *self <= 0x66)
(*self >= 0x30 && *self <= 0x39)
|| (*self >= 0x41 && *self <= 0x46)
|| (*self >= 0x61 && *self <= 0x66)
}
#[inline]
fn is_oct_digit(self) -> bool {
@ -463,7 +467,11 @@ pub trait InputTakeAtPosition: Sized {
/// fails if the produced slice is empty
///
/// *streaming version*: if no element is found matching the condition, this will return `Incomplete`
fn split_at_position1<P, E: ParseError<Self>>(&self, predicate: P, e: ErrorKind) -> IResult<Self, Self, E>
fn split_at_position1<P, E: ParseError<Self>>(
&self,
predicate: P,
e: ErrorKind,
) -> IResult<Self, Self, E>
where
P: Fn(Self::Item) -> bool;
@ -471,7 +479,10 @@ pub trait InputTakeAtPosition: Sized {
/// and returns the input up to this position
///
/// *complete version*: if no element is found matching the condition, this will return the whole input
fn split_at_position_complete<P, E: ParseError<Self>>(&self, predicate: P) -> IResult<Self, Self, E>
fn split_at_position_complete<P, E: ParseError<Self>>(
&self,
predicate: P,
) -> IResult<Self, Self, E>
where
P: Fn(Self::Item) -> bool;
@ -481,12 +492,18 @@ pub trait InputTakeAtPosition: Sized {
/// fails if the produced slice is empty
///
/// *complete version*: if no element is found matching the condition, this will return the whole input
fn split_at_position1_complete<P, E: ParseError<Self>>(&self, predicate: P, e: ErrorKind) -> IResult<Self, Self, E>
fn split_at_position1_complete<P, E: ParseError<Self>>(
&self,
predicate: P,
e: ErrorKind,
) -> IResult<Self, Self, E>
where
P: Fn(Self::Item) -> bool;
}
impl<T: InputLength + InputIter + InputTake + Clone + UnspecializedInput> InputTakeAtPosition for T {
impl<T: InputLength + InputIter + InputTake + Clone + UnspecializedInput> InputTakeAtPosition
for T
{
type Item = <T as InputIter>::Item;
fn split_at_position<P, E: ParseError<Self>>(&self, predicate: P) -> IResult<Self, Self, E>
@ -499,7 +516,11 @@ impl<T: InputLength + InputIter + InputTake + Clone + UnspecializedInput> InputT
}
}
fn split_at_position1<P, E: ParseError<Self>>(&self, predicate: P, e: ErrorKind) -> IResult<Self, Self, E>
fn split_at_position1<P, E: ParseError<Self>>(
&self,
predicate: P,
e: ErrorKind,
) -> IResult<Self, Self, E>
where
P: Fn(Self::Item) -> bool,
{
@ -510,21 +531,34 @@ impl<T: InputLength + InputIter + InputTake + Clone + UnspecializedInput> InputT
}
}
fn split_at_position_complete<P, E: ParseError<Self>>(&self, predicate: P) -> IResult<Self, Self, E>
where P: Fn(Self::Item) -> bool {
fn split_at_position_complete<P, E: ParseError<Self>>(
&self,
predicate: P,
) -> IResult<Self, Self, E>
where
P: Fn(Self::Item) -> bool,
{
match self.split_at_position(predicate) {
Err(Err::Incomplete(_)) => Ok(self.take_split(self.input_len())),
res => res,
}
}
fn split_at_position1_complete<P, E: ParseError<Self>>(&self, predicate: P, e: ErrorKind) -> IResult<Self, Self, E>
where P: Fn(Self::Item) -> bool {
fn split_at_position1_complete<P, E: ParseError<Self>>(
&self,
predicate: P,
e: ErrorKind,
) -> IResult<Self, Self, E>
where
P: Fn(Self::Item) -> bool,
{
match self.split_at_position1(predicate, e) {
Err(Err::Incomplete(_)) => if self.input_len() == 0 {
Err(Err::Error(E::from_error_kind(self.clone(), e)))
} else {
Ok(self.take_split(self.input_len()))
Err(Err::Incomplete(_)) => {
if self.input_len() == 0 {
Err(Err::Error(E::from_error_kind(self.clone(), e)))
} else {
Ok(self.take_split(self.input_len()))
}
}
res => res,
}
@ -544,7 +578,11 @@ impl<'a> InputTakeAtPosition for &'a [u8] {
}
}
fn split_at_position1<P, E: ParseError<Self>>(&self, predicate: P, e: ErrorKind) -> IResult<Self, Self, E>
fn split_at_position1<P, E: ParseError<Self>>(
&self,
predicate: P,
e: ErrorKind,
) -> IResult<Self, Self, E>
where
P: Fn(Self::Item) -> bool,
{
@ -555,16 +593,27 @@ impl<'a> InputTakeAtPosition for &'a [u8] {
}
}
fn split_at_position_complete<P, E: ParseError<Self>>(&self, predicate: P) -> IResult<Self, Self, E>
where P: Fn(Self::Item) -> bool {
fn split_at_position_complete<P, E: ParseError<Self>>(
&self,
predicate: P,
) -> IResult<Self, Self, E>
where
P: Fn(Self::Item) -> bool,
{
match (0..self.len()).find(|b| predicate(self[*b])) {
Some(i) => Ok((&self[i..], &self[..i])),
None => Ok(self.take_split(self.input_len())),
}
}
fn split_at_position1_complete<P, E: ParseError<Self>>(&self, predicate: P, e: ErrorKind) -> IResult<Self, Self, E>
where P: Fn(Self::Item) -> bool {
fn split_at_position1_complete<P, E: ParseError<Self>>(
&self,
predicate: P,
e: ErrorKind,
) -> IResult<Self, Self, E>
where
P: Fn(Self::Item) -> bool,
{
match (0..self.len()).find(|b| predicate(self[*b])) {
Some(0) => Err(Err::Error(E::from_error_kind(self, e))),
Some(i) => Ok((&self[i..], &self[..i])),
@ -574,7 +623,7 @@ impl<'a> InputTakeAtPosition for &'a [u8] {
} else {
Ok(self.take_split(self.input_len()))
}
},
}
}
}
}
@ -592,7 +641,11 @@ impl<'a> InputTakeAtPosition for &'a str {
}
}
fn split_at_position1<P, E: ParseError<Self>>(&self, predicate: P, e: ErrorKind) -> IResult<Self, Self, E>
fn split_at_position1<P, E: ParseError<Self>>(
&self,
predicate: P,
e: ErrorKind,
) -> IResult<Self, Self, E>
where
P: Fn(Self::Item) -> bool,
{
@ -603,16 +656,27 @@ impl<'a> InputTakeAtPosition for &'a str {
}
}
fn split_at_position_complete<P, E: ParseError<Self>>(&self, predicate: P) -> IResult<Self, Self, E>
where P: Fn(Self::Item) -> bool {
fn split_at_position_complete<P, E: ParseError<Self>>(
&self,
predicate: P,
) -> IResult<Self, Self, E>
where
P: Fn(Self::Item) -> bool,
{
match self.find(predicate) {
Some(i) => Ok((&self[i..], &self[..i])),
None => Ok(self.take_split(self.input_len()))
None => Ok(self.take_split(self.input_len())),
}
}
fn split_at_position1_complete<P, E: ParseError<Self>>(&self, predicate: P, e: ErrorKind) -> IResult<Self, Self, E>
where P: Fn(Self::Item) -> bool {
fn split_at_position1_complete<P, E: ParseError<Self>>(
&self,
predicate: P,
e: ErrorKind,
) -> IResult<Self, Self, E>
where
P: Fn(Self::Item) -> bool,
{
match self.find(predicate) {
Some(0) => Err(Err::Error(E::from_error_kind(self, e))),
Some(i) => Ok((&self[i..], &self[..i])),
@ -622,7 +686,7 @@ impl<'a> InputTakeAtPosition for &'a str {
} else {
Ok(self.take_split(self.input_len()))
}
},
}
}
}
}
@ -696,7 +760,9 @@ impl<'a, 'b> Compare<&'b [u8]> for &'a [u8] {
if !reduced.iter().zip(other).all(|(a, b)| match (*a, *b) {
(0..=64, 0..=64) | (91..=96, 91..=96) | (123..=255, 123..=255) => a == b,
(65..=90, 65..=90) | (97..=122, 97..=122) | (65..=90, 97..=122) | (97..=122, 65..=90) => *a | 0b00_10_00_00 == *b | 0b00_10_00_00,
(65..=90, 65..=90) | (97..=122, 97..=122) | (65..=90, 97..=122) | (97..=122, 65..=90) => {
*a | 0b00_10_00_00 == *b | 0b00_10_00_00
}
_ => false,
}) {
CompareResult::Error
@ -708,10 +774,17 @@ impl<'a, 'b> Compare<&'b [u8]> for &'a [u8] {
}
}
impl<T: InputLength + InputIter<Item = u8> + InputTake + UnspecializedInput, O: InputLength + InputIter<Item = u8> + InputTake> Compare<O> for T {
impl<
T: InputLength + InputIter<Item = u8> + InputTake + UnspecializedInput,
O: InputLength + InputIter<Item = u8> + InputTake,
> Compare<O> for T
{
#[inline(always)]
fn compare(&self, t: O) -> CompareResult {
let pos = self.iter_elements().zip(t.iter_elements()).position(|(a, b)| a != b);
let pos = self
.iter_elements()
.zip(t.iter_elements())
.position(|(a, b)| a != b);
match pos {
Some(_) => CompareResult::Error,
@ -733,11 +806,17 @@ impl<T: InputLength + InputIter<Item = u8> + InputTake + UnspecializedInput, O:
let reduced = self.take(m);
let other = t.take(m);
if !reduced.iter_elements().zip(other.iter_elements()).all(|(a, b)| match (a, b) {
(0..=64, 0..=64) | (91..=96, 91..=96) | (123..=255, 123..=255) => a == b,
(65..=90, 65..=90) | (97..=122, 97..=122) | (65..=90, 97..=122) | (97..=122, 65..=90) => a | 0b00_10_00_00 == b | 0b00_10_00_00,
_ => false,
}) {
if !reduced
.iter_elements()
.zip(other.iter_elements())
.all(|(a, b)| match (a, b) {
(0..=64, 0..=64) | (91..=96, 91..=96) | (123..=255, 123..=255) => a == b,
(65..=90, 65..=90) | (97..=122, 97..=122) | (65..=90, 97..=122) | (97..=122, 65..=90) => {
a | 0b00_10_00_00 == b | 0b00_10_00_00
}
_ => false,
})
{
CompareResult::Error
} else if m < blen {
CompareResult::Incomplete
@ -934,39 +1013,39 @@ pub trait Slice<R> {
}
macro_rules! impl_fn_slice {
( $ty:ty ) => {
fn slice(&self, range:$ty) -> Self {
&self[range]
}
( $ty:ty ) => {
fn slice(&self, range: $ty) -> Self {
&self[range]
}
};
}
macro_rules! slice_range_impl {
( [ $for_type:ident ], $ty:ty ) => {
impl<'a, $for_type> Slice<$ty> for &'a [$for_type] {
impl_fn_slice!( $ty );
}
};
( $for_type:ty, $ty:ty ) => {
impl<'a> Slice<$ty> for &'a $for_type {
impl_fn_slice!( $ty );
}
( [ $for_type:ident ], $ty:ty ) => {
impl<'a, $for_type> Slice<$ty> for &'a [$for_type] {
impl_fn_slice!($ty);
}
};
( $for_type:ty, $ty:ty ) => {
impl<'a> Slice<$ty> for &'a $for_type {
impl_fn_slice!($ty);
}
};
}
macro_rules! slice_ranges_impl {
( [ $for_type:ident ] ) => {
slice_range_impl! {[$for_type], Range<usize>}
slice_range_impl! {[$for_type], RangeTo<usize>}
slice_range_impl! {[$for_type], RangeFrom<usize>}
slice_range_impl! {[$for_type], RangeFull}
};
( $for_type:ty ) => {
slice_range_impl! {$for_type, Range<usize>}
slice_range_impl! {$for_type, RangeTo<usize>}
slice_range_impl! {$for_type, RangeFrom<usize>}
slice_range_impl! {$for_type, RangeFull}
}
( [ $for_type:ident ] ) => {
slice_range_impl! {[$for_type], Range<usize>}
slice_range_impl! {[$for_type], RangeTo<usize>}
slice_range_impl! {[$for_type], RangeFrom<usize>}
slice_range_impl! {[$for_type], RangeFull}
};
( $for_type:ty ) => {
slice_range_impl! {$for_type, Range<usize>}
slice_range_impl! {$for_type, RangeTo<usize>}
slice_range_impl! {$for_type, RangeFrom<usize>}
slice_range_impl! {$for_type, RangeFull}
};
}
slice_ranges_impl! {str}
@ -1061,7 +1140,6 @@ array_impls! {
/// abstracts something which can extend an `Extend`
/// used to build modified input slices in `escaped_transform`
pub trait ExtendInto {
/// the current input type is a sequence of that `Item` type.
///
/// example: `u8` for `&[u8]` or `char` for &str`
@ -1106,7 +1184,6 @@ impl ExtendInto for &[u8] {
}
}
#[cfg(feature = "alloc")]
impl ExtendInto for str {
type Item = char;

View File

@ -97,7 +97,6 @@ macro_rules! nom_stringify (
($($args:tt)*) => (stringify!($($args)*));
);
/// Prints a message if the parser fails
///
/// The message prints the `Error` or `Incomplete`
@ -158,16 +157,19 @@ macro_rules! dbg (
/// f(a);
/// ```
#[cfg(feature = "std")]
pub fn dbg_dmp<'a, F, O, E: Debug>(f: F, context: &'static str) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], O, E>
where F: Fn(&'a [u8]) -> IResult<&'a [u8], O, E> {
move |i: &'a [u8]| {
match f(i) {
Err(e) => {
println!("{}: Error({:?}) at:\n{}", context, e, i.to_hex(8));
Err(e)
},
a => a,
}
pub fn dbg_dmp<'a, F, O, E: Debug>(
f: F,
context: &'static str,
) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], O, E>
where
F: Fn(&'a [u8]) -> IResult<&'a [u8], O, E>,
{
move |i: &'a [u8]| match f(i) {
Err(e) => {
println!("{}: Error({:?}) at:\n{}", context, e, i.to_hex(8));
Err(e)
}
a => a,
}
}
@ -211,4 +213,3 @@ macro_rules! dbg_dmp (
dbg_dmp!($i, call!($f));
);
);

View File

@ -795,7 +795,10 @@ macro_rules! sep (
/// ```
///
#[macro_export(local_inner_macros)]
#[deprecated(since = "5.0.0", note = "whitespace parsing only works with macros and will not be updated anymore")]
#[deprecated(
since = "5.0.0",
note = "whitespace parsing only works with macros and will not be updated anymore"
)]
macro_rules! ws (
($i:expr, $($args:tt)*) => (
{
@ -819,21 +822,24 @@ macro_rules! ws (
#[cfg(test)]
#[allow(dead_code)]
mod tests {
use crate::character::complete::multispace0 as sp;
use crate::error::ErrorKind;
use crate::internal::{Err, IResult, Needed};
#[cfg(feature = "alloc")]
use crate::{
error::ParseError,
lib::std::{
fmt::Debug,
string::{String, ToString},
fmt::Debug
}
},
};
use crate::internal::{Err, IResult, Needed};
use crate::character::complete::multispace0 as sp;
use crate::error::ErrorKind;
#[test]
fn spaaaaace() {
assert_eq!(sp::<_,(_,ErrorKind)>(&b" \t abc "[..]), Ok((&b"abc "[..], &b" \t "[..])));
assert_eq!(
sp::<_, (_, ErrorKind)>(&b" \t abc "[..]),
Ok((&b"abc "[..], &b" \t "[..]))
);
}
#[test]
@ -980,8 +986,8 @@ mod tests {
pub struct ErrorStr(String);
#[cfg(feature = "alloc")]
impl<'a> From<(&'a[u8], ErrorKind)> for ErrorStr {
fn from(i: (&'a[u8], ErrorKind)) -> Self {
impl<'a> From<(&'a [u8], ErrorKind)> for ErrorStr {
fn from(i: (&'a [u8], ErrorKind)) -> Self {
ErrorStr(format!("custom error code: {:?}", i))
}
}
@ -1000,7 +1006,10 @@ mod tests {
}
fn append(input: I, kind: ErrorKind, other: Self) -> Self {
ErrorStr(format!("custom error message: ({:?}, {:?}) - {:?}", input, kind, other))
ErrorStr(format!(
"custom error message: ({:?}, {:?}) - {:?}",
input, kind, other
))
}
}
@ -1031,13 +1040,9 @@ mod tests {
}
let a = &b"\tabcd"[..];
assert_eq!(
alt1(a),
Err(Err::Error(error_position!(a, ErrorKind::Alt)))
);
assert_eq!(alt1(a), Err(Err::Error(error_position!(a, ErrorKind::Alt))));
assert_eq!(alt2(a), Ok((&b""[..], a)));
assert_eq!(alt3(a), Ok((a, &b""[..])));
}
named!(str_parse(&str) -> &str, ws!(tag!("test")));

View File

@ -1,15 +1,14 @@
extern crate nom;
use nom::{
IResult,
branch::alt,
combinator::map_res,
character::complete::char,
bytes::complete::tag,
character::complete::char,
character::complete::{digit1 as digit, space0 as space},
combinator::map_res,
multi::fold_many0,
sequence::{delimited, pair}
sequence::{delimited, pair},
IResult,
};
// Parser definition
@ -18,15 +17,7 @@ use std::str::FromStr;
// We parse any expr surrounded by parens, ignoring all whitespaces around those
fn parens(i: &str) -> IResult<&str, i64> {
delimited(
space,
delimited(
tag("("),
expr,
tag(")")
),
space
)(i)
delimited(space, delimited(tag("("), expr, tag(")")), space)(i)
}
// We transform an integer string into a i64, ignoring surrounding whitespaces
@ -36,7 +27,7 @@ fn parens(i: &str) -> IResult<&str, i64> {
fn factor(i: &str) -> IResult<&str, i64> {
alt((
map_res(delimited(space, digit, space), FromStr::from_str),
parens
parens,
))(i)
}
@ -50,8 +41,12 @@ fn term(i: &str) -> IResult<&str, i64> {
pair(alt((char('*'), char('/'))), factor),
init,
|acc, (op, val): (char, i64)| {
if op == '*' { acc * val } else { acc / val }
}
if op == '*' {
acc * val
} else {
acc / val
}
},
)(i)
}
@ -62,8 +57,12 @@ fn expr(i: &str) -> IResult<&str, i64> {
pair(alt((char('+'), char('-'))), term),
init,
|acc, (op, val): (char, i64)| {
if op == '+' { acc + val } else { acc - val }
}
if op == '+' {
acc + val
} else {
acc - val
}
},
)(i)
}
@ -78,32 +77,20 @@ fn factor_test() {
#[test]
fn term_test() {
assert_eq!(term(" 12 *2 / 3"), Ok(("", 8)));
assert_eq!(
term(" 2* 3 *2 *2 / 3"),
Ok(("", 8))
);
assert_eq!(term(" 2* 3 *2 *2 / 3"), Ok(("", 8)));
assert_eq!(term(" 48 / 3/2"), Ok(("", 8)));
}
#[test]
fn expr_test() {
assert_eq!(expr(" 1 + 2 "), Ok(("", 3)));
assert_eq!(
expr(" 12 + 6 - 4+ 3"),
Ok(("", 17))
);
assert_eq!(expr(" 12 + 6 - 4+ 3"), Ok(("", 17)));
assert_eq!(expr(" 1 + 2*3 + 4"), Ok(("", 11)));
}
#[test]
fn parens_test() {
assert_eq!(expr(" ( 2 )"), Ok(("", 2)));
assert_eq!(
expr(" 2* ( 3 + 4 ) "),
Ok(("", 14))
);
assert_eq!(
expr(" 2*2 / ( 5 - 1) + 3"),
Ok(("", 4))
);
assert_eq!(expr(" 2* ( 3 + 4 ) "), Ok(("", 14)));
assert_eq!(expr(" 2*2 / ( 5 - 1) + 3"), Ok(("", 4)));
}

View File

@ -6,13 +6,13 @@ use std::fmt::{Debug, Display, Formatter};
use std::str::FromStr;
use nom::{
IResult,
character::complete::{digit1 as digit, multispace0 as multispace},
sequence::{preceded, delimited},
combinator::{map, map_res},
multi::many0,
branch::alt,
bytes::complete::tag,
character::complete::{digit1 as digit, multispace0 as multispace},
combinator::{map, map_res},
multi::many0,
sequence::{delimited, preceded},
IResult,
};
pub enum Expr {
@ -63,25 +63,18 @@ impl Debug for Expr {
fn parens(i: &str) -> IResult<&str, Expr> {
delimited(
multispace,
delimited(
tag("("),
map(expr, |e| Expr::Paren(Box::new(e))),
tag(")")
),
multispace
delimited(tag("("), map(expr, |e| Expr::Paren(Box::new(e))), tag(")")),
multispace,
)(i)
}
fn factor(i: &str) -> IResult<&str, Expr> {
alt((
map(
map_res(
delimited(multispace, digit, multispace),
FromStr::from_str
),
Expr::Value
map_res(delimited(multispace, digit, multispace), FromStr::from_str),
Expr::Value,
),
parens
parens,
))(i)
}
@ -101,14 +94,13 @@ fn term(i: &str) -> IResult<&str, Expr> {
let (i, initial) = factor(i)?;
let (i, remainder) = many0(alt((
|i| {
let(i, mul) = preceded(tag("*"), factor)(i)?;
Ok((i,(Oper::Mul, mul)))
let (i, mul) = preceded(tag("*"), factor)(i)?;
Ok((i, (Oper::Mul, mul)))
},
|i| {
let(i, div) = preceded(tag("/"), factor)(i)?;
let (i, div) = preceded(tag("/"), factor)(i)?;
Ok((i, (Oper::Div, div)))
},
)))(i)?;
Ok((i, fold_exprs(initial, remainder)))
@ -118,14 +110,13 @@ fn expr(i: &str) -> IResult<&str, Expr> {
let (i, initial) = term(i)?;
let (i, remainder) = many0(alt((
|i| {
let(i, add) = preceded(tag("+"), term)(i)?;
Ok((i,(Oper::Add, add)))
let (i, add) = preceded(tag("+"), term)(i)?;
Ok((i, (Oper::Add, add)))
},
|i| {
let(i, sub) = preceded(tag("-"), term)(i)?;
let (i, sub) = preceded(tag("-"), term)(i)?;
Ok((i, (Oper::Sub, sub)))
},
)))(i)?;
Ok((i, fold_exprs(initial, remainder)))

View File

@ -1,9 +1,9 @@
extern crate nom;
use nom::IResult;
use nom::bytes::complete::{tag, take_while_m_n};
use nom::combinator::map_res;
use nom::sequence::tuple;
use nom::IResult;
#[derive(Debug, PartialEq)]
pub struct Color {
@ -21,10 +21,7 @@ fn is_hex_digit(c: char) -> bool {
}
fn hex_primary(input: &str) -> IResult<&str, u8> {
map_res(
take_while_m_n(2, 2, is_hex_digit),
from_hex
)(input)
map_res(take_while_m_n(2, 2, is_hex_digit), from_hex)(input)
}
fn hex_color(input: &str) -> IResult<&str, Color> {
@ -34,7 +31,6 @@ fn hex_color(input: &str) -> IResult<&str, Color> {
Ok((input, Color { red, green, blue }))
}
#[test]
fn parse_color() {
assert_eq!(

View File

@ -4,9 +4,9 @@
#[macro_use]
extern crate nom;
use nom::IResult;
use nom::error::{ErrorKind,ParseError};
use nom::character::streaming::digit1 as digit;
use nom::error::{ErrorKind, ParseError};
use nom::IResult;
use std::convert::From;
@ -26,9 +26,7 @@ impl<'a> ParseError<&'a str> for CustomError {
fn append(_: &'a str, kind: ErrorKind, other: CustomError) -> Self {
CustomError(format!("{:?}\nerror code was: {:?}", other, kind))
}
}
fn test1(input: &str) -> IResult<&str, &str, CustomError> {
@ -42,9 +40,7 @@ fn test2(input: &str) -> IResult<&str, &str, CustomError> {
}
fn test3(input: &str) -> IResult<&str, &str, CustomError> {
verify!(input, test1, |s: &str| {
s.starts_with("abcd")
})
verify!(input, test1, |s: &str| { s.starts_with("abcd") })
}
#[cfg(feature = "alloc")]

View File

@ -1,25 +1,28 @@
use nom::{Err, error::ErrorKind, IResult};
use nom::character::complete::digit1;
use nom::bytes::complete::escaped;
use nom::character::complete::digit1;
use nom::character::complete::one_of;
use nom::{error::ErrorKind, Err, IResult};
fn esc(s: &str) -> IResult<&str, &str> {
escaped(digit1, '\\', one_of("\"n\\"))(s)
escaped(digit1, '\\', one_of("\"n\\"))(s)
}
#[cfg(feature="alloc")]
#[cfg(feature = "alloc")]
fn esc_trans(s: &str) -> IResult<&str, String> {
use nom::bytes::complete::{escaped_transform, tag};
escaped_transform(digit1, '\\', tag("n"))(s)
use nom::bytes::complete::{escaped_transform, tag};
escaped_transform(digit1, '\\', tag("n"))(s)
}
#[test]
fn test_escaped() {
assert_eq!(esc("abcd"), Err(Err::Error(("abcd", ErrorKind::Escaped))));
assert_eq!(esc("abcd"), Err(Err::Error(("abcd", ErrorKind::Escaped))));
}
#[test]
#[cfg(feature="alloc")]
#[cfg(feature = "alloc")]
fn test_escaped_transform() {
assert_eq!(esc_trans("abcd"), Err(Err::Error(("abcd", ErrorKind::EscapedTransform))));
assert_eq!(
esc_trans("abcd"),
Err(Err::Error(("abcd", ErrorKind::EscapedTransform)))
);
}

View File

@ -25,7 +25,8 @@ named!(
pair!(opt!(alt!(tag!("+") | tag!("-"))), unsigned_float),
|(sign, value): (Option<&[u8]>, f32)| sign
.and_then(|s| if s[0] == b'-' { Some(-1f32) } else { None })
.unwrap_or(1f32) * value
.unwrap_or(1f32)
* value
)
);

View File

@ -8,8 +8,8 @@
#[macro_use]
extern crate nom;
use nom::character::{is_digit, streaming::alpha1 as alpha};
use std::str;
use nom::character::{streaming::alpha1 as alpha, is_digit};
// issue #617
named!(multi<&[u8], () >, fold_many0!( take_while1!( is_digit ), (), |_, _| {}));
@ -28,7 +28,8 @@ named!(
tag!("\n\t"),
map_res!(take_while!(call!(|c| c != b'\n')), std::str::from_utf8)
)
) >> (rest)
)
>> (rest)
)
);

View File

@ -2,21 +2,26 @@
extern crate nom;
use nom::{
IResult,
bytes::complete::take_while,
sequence::delimited,
character::complete::{
alphanumeric1 as alphanumeric, char, multispace0 as multispace, space0 as space,
},
combinator::map_res,
character::complete::{char, alphanumeric1 as alphanumeric, multispace0 as multispace, space0 as space}
sequence::delimited,
IResult,
};
use std::str;
use std::collections::HashMap;
use std::str;
fn category(i: &[u8]) -> IResult<&[u8], &str> {
map_res(delimited(char('['), take_while(|c| c != b']'), char(']')), str::from_utf8)(i)
map_res(
delimited(char('['), take_while(|c| c != b']'), char(']')),
str::from_utf8,
)(i)
}
fn complete_byte_slice_to_str<'a>(s: &'a[u8]) -> Result<&'a str, str::Utf8Error> {
fn complete_byte_slice_to_str<'a>(s: &'a [u8]) -> Result<&'a str, str::Utf8Error> {
str::from_utf8(s)
}

View File

@ -2,11 +2,11 @@
extern crate nom;
use nom::{
IResult,
bytes::complete::{is_a, take_while},
character::complete::{alphanumeric1 as alphanumeric, char, space0 as space},
combinator::opt,
bytes::complete::{take_while, is_a},
sequence::{delimited, terminated},
character::complete::{char, alphanumeric1 as alphanumeric, space0 as space}
IResult,
};
use std::collections::HashMap;
@ -24,7 +24,10 @@ fn space_or_line_ending(i: &str) -> IResult<&str, &str> {
}
fn category(i: &str) -> IResult<&str, &str> {
terminated(delimited(char('['), take_while(|c| c != ']'), char(']')), opt(is_a(" \r\n")))(i)
terminated(
delimited(char('['), take_while(|c| c != ']'), char(']')),
opt(is_a(" \r\n")),
)(i)
}
named!(key_value <&str,(&str,&str)>,

View File

@ -5,7 +5,12 @@
#[macro_use]
extern crate nom;
use nom::{character::{is_digit, streaming::space1 as space}, Err, IResult, Needed, error::ErrorKind, number::streaming::le_u64};
use nom::{
character::{is_digit, streaming::space1 as space},
error::ErrorKind,
number::streaming::le_u64,
Err, IResult, Needed,
};
#[allow(dead_code)]
struct Range {
@ -68,7 +73,10 @@ fn issue_58() {
#[cfg(feature = "std")]
mod parse_int {
use nom::HexDisplay;
use nom::{IResult, character::streaming::{digit1 as digit, space1 as space}};
use nom::{
character::streaming::{digit1 as digit, space1 as space},
IResult,
};
use std::str;
named!(parse_ints<Vec<i32>>, many0!(spaces_or_int));
@ -77,16 +85,18 @@ mod parse_int {
println!("{}", input.to_hex(8));
do_parse!(
input,
opt!(complete!(space)) >> res: map!(complete!(digit), |x| {
println!("x: {:?}", x);
let result = str::from_utf8(x).unwrap();
println!("Result: {}", result);
println!("int is empty?: {}", x.is_empty());
match result.parse() {
Ok(i) => i,
Err(e) => panic!("UH OH! NOT A DIGIT! {:?}", e),
}
}) >> (res)
opt!(complete!(space))
>> res: map!(complete!(digit), |x| {
println!("x: {:?}", x);
let result = str::from_utf8(x).unwrap();
println!("Result: {}", result);
println!("int is empty?: {}", x.is_empty());
match result.parse() {
Ok(i) => i,
Err(e) => panic!("UH OH! NOT A DIGIT! {:?}", e),
}
})
>> (res)
)
}
@ -203,24 +213,24 @@ named!(issue_724<&str, i32>,
#[test]
fn issue_752() {
assert_eq!(
Err::Error(("ab", nom::error::ErrorKind::ParseTo)),
parse_to!("ab", usize).unwrap_err()
)
assert_eq!(
Err::Error(("ab", nom::error::ErrorKind::ParseTo)),
parse_to!("ab", usize).unwrap_err()
)
}
fn atom_specials(c: u8) -> bool {
c == b'q'
c == b'q'
}
named!(
capability<&str>,
do_parse!(tag!(" ") >> _atom: map_res!(take_till1!(atom_specials), std::str::from_utf8) >> ("a"))
capability<&str>,
do_parse!(tag!(" ") >> _atom: map_res!(take_till1!(atom_specials), std::str::from_utf8) >> ("a"))
);
#[test]
fn issue_759() {
assert_eq!(capability(b" abcqd"), Ok((&b"qd"[..], "a")));
assert_eq!(capability(b" abcqd"), Ok((&b"qd"[..], "a")));
}
named_args!(issue_771(count: usize)<Vec<u32>>,
@ -237,24 +247,27 @@ mod issue_780 {
}
// issue 617
named!(digits, take_while1!( is_digit ));
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 {
use nom::{Err, number::streaming::be_f64, error::ErrorKind};
use nom::{error::ErrorKind, number::streaming::be_f64, Err};
pub type Input<'a> = &'a [u8];
#[derive(PartialEq, Debug, Clone)]
struct Data {
c: f64,
v: Vec<f64>
c: f64,
v: Vec<f64>,
}
fn list<'a,'b>(input: Input<'a>, _cs: &'b f64) -> Result<(Input<'a>,Vec<f64>), Err<(&'a [u8], ErrorKind)>> {
separated_list!(input, complete!(tag!(",")), complete!(be_f64))
fn list<'a, 'b>(
input: Input<'a>,
_cs: &'b f64,
) -> Result<(Input<'a>, Vec<f64>), Err<(&'a [u8], ErrorKind)>> {
separated_list!(input, complete!(tag!(",")), complete!(be_f64))
}
named!(data<Input,Data>, map!(
@ -278,7 +291,10 @@ named!(issue_775, take_till1!(|_| true));
fn issue_848_overflow_incomplete_bits_to_bytes() {
named!(take, take!(0x2000000000000000));
named!(parser<&[u8], &[u8]>, bits!(bytes!(take)));
assert_eq!(parser(&b""[..]), Err(Err::Failure(error_position!(&b""[..], ErrorKind::TooLarge))));
assert_eq!(
parser(&b""[..]),
Err(Err::Failure(error_position!(&b""[..], ErrorKind::TooLarge)))
);
}
#[test]
@ -293,17 +309,17 @@ fn issue_942() {
#[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!())));
use nom::character::complete::char;
use nom::multi::many_m_n;
let parser = many_m_n::<_, _, (), _>(0, 0, char('a'));
assert_eq!(parser("aaa"), Ok(("aaa", vec!())));
}
#[test]
fn issue_1027_convert_error_panic_nonempty() {
use nom::error::{VerboseError, convert_error};
use nom::sequence::pair;
use nom::character::complete::char;
use nom::error::{convert_error, VerboseError};
use nom::sequence::pair;
let input = "a";
@ -314,5 +330,8 @@ fn issue_1027_convert_error_panic_nonempty() {
};
let msg = convert_error(&input, err);
assert_eq!(msg, "0: at line 1:\na\n ^\nexpected \'b\', got end of input\n\n");
assert_eq!(
msg,
"0: at line 1:\na\n ^\nexpected \'b\', got end of input\n\n"
);
}

View File

@ -6,8 +6,8 @@ extern crate nom;
use nom::{character::is_alphanumeric, number::complete::recognize_float};
use std::str;
use std::collections::HashMap;
use std::str;
#[derive(Debug, PartialEq)]
pub enum JsonValue {
@ -50,7 +50,11 @@ named!(
named!(
hash<HashMap<String, JsonValue>>,
ws!(map!(
delimited!(char!('{'), separated_list0!(char!(','), key_value), char!('}')),
delimited!(
char!('{'),
separated_list0!(char!(','), key_value),
char!('}')
),
|tuple_vec| {
let mut h: HashMap<String, JsonValue> = HashMap::new();
for (k, v) in tuple_vec {
@ -64,17 +68,16 @@ named!(
named!(
value<JsonValue>,
ws!(alt!(
hash => { |h| JsonValue::Object(h) } |
array => { |v| JsonValue::Array(v) } |
string => { |s| JsonValue::Str(String::from(s)) } |
float => { |num| JsonValue::Num(num) }
))
hash => { |h| JsonValue::Object(h) } |
array => { |v| JsonValue::Array(v) } |
string => { |s| JsonValue::Str(String::from(s)) } |
float => { |num| JsonValue::Num(num) }
))
);
#[test]
fn json_object() {
let input =
r#"{
let input = r#"{
"a": 42,
"b": "x"
}\0"#;
@ -89,16 +92,12 @@ fn json_object() {
#[test]
fn json_array() {
let input =
r#"[
let input = r#"[
42,
"x"
]\0"#;
let expected_vec = vec![
JsonValue::Num(42f32),
JsonValue::Str(String::from("x"))
];
let expected_vec = vec![JsonValue::Num(42f32), JsonValue::Str(String::from("x"))];
let expected = JsonValue::Array(expected_vec);
assert_eq!(expected, value(input.as_bytes()).unwrap().1);

View File

@ -4,9 +4,9 @@
extern crate nom;
use nom::{
IResult, Needed, Err,
error::ErrorKind,
number::streaming::{be_u16, be_u32, be_u64, be_f32}
number::streaming::{be_f32, be_u16, be_u32, be_u64},
Err, IResult, Needed,
};
use std::str;
@ -316,4 +316,3 @@ named!(moov_header<&[u8],MP4BoxHeader>,
(MP4BoxHeader{ length: length, tag: tag})
)
);

View File

@ -1,10 +1,10 @@
extern crate nom;
use nom::{
IResult,
character::complete::{alphanumeric1 as alphanumeric, line_ending as eol},
multi::many0,
sequence::terminated,
character::complete::{alphanumeric1 as alphanumeric, line_ending as eol}
IResult,
};
pub fn end_of_line(input: &str) -> IResult<&str, &str> {
@ -26,10 +26,7 @@ pub fn read_lines(input: &str) -> IResult<&str, Vec<&str>> {
#[cfg(feature = "alloc")]
#[test]
fn read_lines_test() {
let res = Ok((
"",
vec!["Duck", "Dog", "Cow"],
));
let res = Ok(("", vec!["Duck", "Dog", "Cow"]));
assert_eq!(read_lines("Duck\nDog\nCow\n"), res);
assert_eq!(read_lines("Duck\nDog\nCow"), res);

View File

@ -3,9 +3,9 @@ extern crate nom;
use nom::{
branch::alt,
sequence::{delimited, pair, preceded},
bytes::complete::tag,
character::complete::{digit1 as digit, space0 as space},
bytes::complete::tag
sequence::{delimited, pair, preceded},
};
// Parser definition
@ -43,7 +43,7 @@ named_args!(brackets<'a>(open_tag: &str, close_tag: &str) <&'a[u8], i64>,
))
);
fn byte_slice_to_str<'a>(s: &'a[u8]) -> Result<&'a str, str::Utf8Error> {
fn byte_slice_to_str<'a>(s: &'a [u8]) -> Result<&'a str, str::Utf8Error> {
str::from_utf8(s)
}
@ -94,68 +94,29 @@ named!(expr <&[u8], i64>, do_parse!(
#[test]
fn factor_test() {
assert_eq!(
factor(&b"3"[..]),
Ok((&b""[..], 3))
);
assert_eq!(
factor(&b" 12"[..]),
Ok((&b""[..], 12))
);
assert_eq!(
factor(&b"537 "[..]),
Ok((&b""[..], 537))
);
assert_eq!(
factor(&b" 24 "[..]),
Ok((&b""[..], 24))
);
assert_eq!(factor(&b"3"[..]), Ok((&b""[..], 3)));
assert_eq!(factor(&b" 12"[..]), Ok((&b""[..], 12)));
assert_eq!(factor(&b"537 "[..]), Ok((&b""[..], 537)));
assert_eq!(factor(&b" 24 "[..]), Ok((&b""[..], 24)));
}
#[test]
fn term_test() {
assert_eq!(
term(&b" 12 *2 / 3"[..]),
Ok((&b""[..], 8))
);
assert_eq!(
term(&b" 2* 3 *2 *2 / 3"[..]),
Ok((&b""[..], 8))
);
assert_eq!(
term(&b" 48 / 3/2"[..]),
Ok((&b""[..], 8))
);
assert_eq!(term(&b" 12 *2 / 3"[..]), Ok((&b""[..], 8)));
assert_eq!(term(&b" 2* 3 *2 *2 / 3"[..]), Ok((&b""[..], 8)));
assert_eq!(term(&b" 48 / 3/2"[..]), Ok((&b""[..], 8)));
}
#[test]
fn expr_test() {
assert_eq!(
expr(&b" 1 + 2 "[..]),
Ok((&b""[..], 3))
);
assert_eq!(
expr(&b" 12 + 6 - 4+ 3"[..]),
Ok((&b""[..], 17))
);
assert_eq!(
expr(&b" 1 + 2*3 + 4"[..]),
Ok((&b""[..], 11))
);
assert_eq!(expr(&b" 1 + 2 "[..]), Ok((&b""[..], 3)));
assert_eq!(expr(&b" 12 + 6 - 4+ 3"[..]), Ok((&b""[..], 17)));
assert_eq!(expr(&b" 1 + 2*3 + 4"[..]), Ok((&b""[..], 11)));
}
#[test]
fn parens_test() {
assert_eq!(
expr(&b" ( 2 )"[..]),
Ok((&b""[..], 2))
);
assert_eq!(
expr(&b" 2* ( 3 + 4 ) "[..]),
Ok((&b""[..], 14))
);
assert_eq!(
expr(&b" 2*2 / ( 5 - 1) + 3"[..]),
Ok((&b""[..], 4))
);
assert_eq!(expr(&b" ( 2 )"[..]), Ok((&b""[..], 2)));
assert_eq!(expr(&b" 2* ( 3 + 4 ) "[..]), Ok((&b""[..], 14)));
assert_eq!(expr(&b" 2*2 / ( 5 - 1) + 3"[..]), Ok((&b""[..], 4)));
}

View File

@ -4,9 +4,9 @@
#[macro_use]
extern crate nom;
use nom::{Err, Needed};
#[cfg(feature = "alloc")]
use nom::number::streaming::be_u64;
use nom::{Err, Needed};
// Parser definition