mirror of
https://gitee.com/openharmony/third_party_rust_nom
synced 2024-11-26 17:20:29 +00:00
formatting
This commit is contained in:
parent
ac34e5ac11
commit
afad7bf93e
@ -43,7 +43,8 @@ named!(
|
||||
} else {
|
||||
acc / val
|
||||
}
|
||||
) >> (res)
|
||||
)
|
||||
>> (res)
|
||||
)
|
||||
);
|
||||
|
||||
@ -60,7 +61,8 @@ named!(
|
||||
} else {
|
||||
acc - val
|
||||
}
|
||||
) >> (res)
|
||||
)
|
||||
>> (res)
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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
334
examples/json_iterator.rs
Normal 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
17
examples/macro.rs
Normal 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);
|
||||
}
|
@ -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)
|
||||
);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -1,3 +1,2 @@
|
||||
tab_spaces = 2
|
||||
struct_field_align_threshold = 100
|
||||
max_width = 140
|
||||
max_width = 100
|
||||
|
@ -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,
|
||||
|
@ -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))));
|
||||
}
|
||||
}
|
||||
|
@ -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>,
|
||||
|
@ -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,
|
||||
|
@ -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"[..]);
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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", "ø")));
|
||||
}
|
||||
}
|
||||
|
@ -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èDEF;"[..]), Ok((&b";"[..], String::from("abèDEF"))));
|
||||
assert_eq!(esc2(&b"abèDàEF;"[..]), Ok((&b";"[..], String::from("abèDàEF"))));
|
||||
assert_eq!(
|
||||
esc2(&b"abèDEF;"[..]),
|
||||
Ok((&b";"[..], String::from("abèDEF")))
|
||||
);
|
||||
assert_eq!(
|
||||
esc2(&b"abèDà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èDEF;"), Ok((";", String::from("abèDEF"))));
|
||||
assert_eq!(esc2("abèDàEF;"), Ok((";", String::from("abèDàEF"))));
|
||||
assert_eq!(
|
||||
esc2("abèDà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]
|
||||
|
@ -2,6 +2,5 @@
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
pub mod streaming;
|
||||
pub mod complete;
|
||||
|
||||
pub mod streaming;
|
||||
|
@ -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)
|
||||
|
||||
}
|
||||
|
@ -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)))
|
||||
|
@ -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() {
|
||||
|
@ -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'
|
||||
}
|
||||
|
||||
|
@ -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)))
|
||||
|
@ -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>);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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)))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
72
src/error.rs
72
src/error.rs
@ -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\
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
21
src/lib.rs
21
src/lib.rs
@ -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")]
|
||||
|
@ -17,4 +17,3 @@ macro_rules! call_m (
|
||||
macro_rules! apply_m (
|
||||
($($args:tt)*) => (compile_error!("method combinators moved to the nom-methods crate"););
|
||||
);
|
||||
|
||||
|
@ -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
|
||||
)))
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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,
|
||||
}
|
||||
|
||||
|
@ -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)))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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"[..],
|
||||
|
@ -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"[..],
|
||||
|
@ -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)]
|
||||
|
@ -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)))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
45
src/str.rs
45
src/str.rs
@ -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("點");
|
||||
}
|
||||
|
215
src/traits.rs
215
src/traits.rs
@ -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;
|
||||
|
25
src/util.rs
25
src/util.rs
@ -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));
|
||||
);
|
||||
);
|
||||
|
||||
|
@ -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")));
|
||||
|
@ -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)));
|
||||
}
|
||||
|
@ -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)))
|
||||
|
@ -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!(
|
||||
|
@ -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")]
|
||||
|
@ -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)))
|
||||
);
|
||||
}
|
||||
|
@ -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
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -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)
|
||||
)
|
||||
);
|
||||
|
||||
|
17
tests/ini.rs
17
tests/ini.rs
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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)>,
|
||||
|
@ -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"
|
||||
);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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})
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)));
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user