Skip to content

Commit

Permalink
Fix the test errors from introducing ParsingError
Browse files Browse the repository at this point in the history
  • Loading branch information
Marwes committed Oct 11, 2017
1 parent 706611f commit bee8f9c
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 129 deletions.
4 changes: 2 additions & 2 deletions benches/http.rs
Expand Up @@ -7,7 +7,7 @@ use bencher::{black_box, Bencher};
use std::fmt;

use combine::*;
use combine::primitives::{RangeStream, SimpleStream};
use combine::primitives::{RangeStream, SimpleStream, UnexpectedParse};
use combine::range::{range, take_while1};

#[derive(Debug)]
Expand Down Expand Up @@ -144,7 +144,7 @@ fn http_requests_bench<'a, I>(b: &mut Bencher, buffer: I)
b.iter(|| {
let mut buf = black_box(buffer.clone());

while buf.clone().uncons().is_ok() {
while buf.clone().uncons::<UnexpectedParse>().is_ok() {
// Needed for inferrence for many(message_header)
match parse_http_request(buf) {
Ok(((_, _), b)) => {
Expand Down
34 changes: 18 additions & 16 deletions benches/mp4.rs
Expand Up @@ -2,8 +2,8 @@
#[macro_use]
extern crate bencher;

extern crate combine;
extern crate byteorder;
extern crate combine;

use bencher::{black_box, Bencher};

Expand Down Expand Up @@ -42,26 +42,28 @@ fn parse_mp4(data: &[u8]) -> Result<(Vec<MP4Box>, &[u8]), StreamError<&[u8]>> {
take(4),
many(brand_name()),
).map(|(_, m, v, c)| {
MP4Box::Ftyp(FileType {
major_brand: m,
major_brand_version: v,
compatible_brands: c,
})
});
MP4Box::Ftyp(FileType {
major_brand: m,
major_brand_version: v,
compatible_brands: c,
})
});

let mp4_box = take(4)
.map(BigEndian::read_u32)
.then(|offset| take(offset as usize - 4));
let mut box_parser = filetype_box
.or(range(&b"moov"[..]).map(|_| MP4Box::Moov))
.or(range(&b"mdat"[..]).map(|_| MP4Box::Mdat))
.or(range(&b"free"[..]).map(|_| MP4Box::Free))
.or(range(&b"skip"[..]).map(|_| MP4Box::Skip))
.or(range(&b"wide"[..]).map(|_| MP4Box::Wide))
.or(value(MP4Box::Unknown));
let data_interpreter = mp4_box.flat_map(|box_data| box_parser.parse(box_data).map(|t| t.0));
let mut box_parser = choice((
filetype_box,
range(&b"moov"[..]).map(|_| MP4Box::Moov),
range(&b"mdat"[..]).map(|_| MP4Box::Mdat),
range(&b"free"[..]).map(|_| MP4Box::Free),
range(&b"skip"[..]).map(|_| MP4Box::Skip),
range(&b"wide"[..]).map(|_| MP4Box::Wide),
value(MP4Box::Unknown),
));
let data_interpreter = mp4_box.flat_map(|box_data| box_parser.simple_parse(box_data).map(|t| t.0));

many(data_interpreter).parse(data)
many(data_interpreter).simple_parse(data)
}

fn run_test(b: &mut Bencher, data: &[u8]) {
Expand Down
70 changes: 35 additions & 35 deletions src/combinator.rs
@@ -1,7 +1,7 @@
use std::iter::FromIterator;
use std::marker::PhantomData;
use primitives::{Consumed, ConsumedResult, ParseResult, Parser, ParsingError, Positioned,
SimpleInfo, Stream, StreamOnce, StreamingError, Tracked};
SimpleInfo, Stream, StreamOnce, StreamingError, Tracked, UnexpectedParse};
use primitives::FastResult::*;

use ErrorOffset;
Expand Down Expand Up @@ -316,7 +316,7 @@ where
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::primitives::Info;
/// # use combine::primitives::SimpleInfo;
/// # fn main() {
/// use std::ascii::AsciiExt;
/// let result = tokens(|l, r| l.eq_ignore_ascii_case(&r), "abc".into(), "abc".chars())
Expand All @@ -325,7 +325,7 @@ where
/// assert_eq!(result, Ok("abc"));
/// let result = tokens(
/// |&l, r| (if l < r { r - l } else { l - r }) <= 2,
/// Info::Range(&b"025"[..]),
/// SimpleInfo::Range(&b"025"[..]),
/// &b"025"[..]
/// )
/// .parse(&b"123"[..])
Expand Down Expand Up @@ -483,15 +483,15 @@ where
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::primitives::{Error, SimpleInfo};
/// # use combine::primitives::{Error, Info};
/// # use combine::state::State;
/// # fn main() {
/// let mut parser = many1(none_of(b"abc".iter().cloned()));
/// let result = parser.parse(State::new(&b"xyb"[..]))
/// let result = parser.simple_parse(State::new(&b"xyb"[..]))
/// .map(|(output, input)| (output, input.input));
/// assert_eq!(result, Ok((b"xy"[..].to_owned(), &b"b"[..])));
///
/// let result = parser.parse(State::new(&b"ab"[..]));
/// let result = parser.simple_parse(State::new(&b"ab"[..]));
/// assert_eq!(result, Err(ParseError {
/// position: 0,
/// errors: vec![
Expand Down Expand Up @@ -1028,17 +1028,17 @@ where
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::primitives::Error;
/// # use combine::primitives::StreamingError;
/// # fn main() {
/// let result = unexpected("token")
/// .parse("a");
/// .simple_parse("a");
/// assert!(result.is_err());
/// assert!(
/// result.err()
/// .unwrap()
/// .errors
/// .iter()
/// .any(|m| *m == <Self::Input as StreamOnce>::Error::Unexpected("token".into()))
/// .any(|m| *m == StreamingError::unexpected("token".into()))
/// );
/// # }
/// ```
Expand Down Expand Up @@ -1128,8 +1128,8 @@ where

#[inline]
fn parse_lazy(&mut self, input: I) -> ConsumedResult<(), I> {
match input.clone().uncons() {
Err(ref err) if *err == StreamingError::end_of_input() => EmptyOk(((), input)),
match input.clone().uncons::<UnexpectedParse>() {
Err(ref err) if *err == UnexpectedParse::Eoi => EmptyOk(((), input)),
_ => EmptyErr(
<Self::Input as StreamOnce>::Error::empty(input.position()).into(),
),
Expand All @@ -1150,8 +1150,8 @@ where
/// # use combine::state::SourcePosition;
/// # fn main() {
/// let mut parser = eof();
/// assert_eq!(parser.parse(State::new("")), Ok(((), State::new(""))));
/// assert_eq!(parser.parse(State::new("x")), Err(ParseError {
/// assert_eq!(parser.simple_parse(State::new("")), Ok(((), State::new(""))));
/// assert_eq!(parser.simple_parse(State::new("x")), Err(ParseError {
/// position: SourcePosition::default(),
/// errors: vec![
/// Error::Unexpected('x'.into()),
Expand All @@ -1172,13 +1172,13 @@ pub struct Iter<P: Parser> {
parser: P,
input: P::Input,
consumed: bool,
state: State<P::Input>,
state: State<<P::Input as StreamOnce>::Error>,
}

enum State<I: Stream> {
enum State<E> {
Ok,
EmptyErr,
ConsumedErr(I::Error),
ConsumedErr(E),
}

impl<P: Parser> Iter<P> {
Expand Down Expand Up @@ -1496,10 +1496,10 @@ where
/// # use combine::state::SourcePosition;
/// # fn main() {
/// let mut parser = sep_by1(digit(), token(','));
/// let result_ok = parser.parse(State::new("1,2,3"))
/// let result_ok = parser.simple_parse(State::new("1,2,3"))
/// .map(|(vec, state)| (vec, state.input));
/// assert_eq!(result_ok, Ok((vec!['1', '2', '3'], "")));
/// let result_err = parser.parse(State::new(""));
/// let result_err = parser.simple_parse(State::new(""));
/// assert_eq!(result_err, Err(ParseError {
/// position: SourcePosition::default(),
/// errors: vec![
Expand Down Expand Up @@ -1638,10 +1638,10 @@ where
/// # use combine::state::SourcePosition;
/// # fn main() {
/// let mut parser = sep_end_by1(digit(), token(';'));
/// let result_ok = parser.parse(State::new("1;2;3;"))
/// let result_ok = parser.simple_parse(State::new("1;2;3;"))
/// .map(|(vec, state)| (vec, state.input));
/// assert_eq!(result_ok, Ok((vec!['1', '2', '3'], "")));
/// let result_err = parser.parse(State::new(""));
/// let result_err = parser.simple_parse(State::new(""));
/// assert_eq!(result_err, Err(ParseError {
/// position: SourcePosition::default(),
/// errors: vec![
Expand Down Expand Up @@ -1685,11 +1685,11 @@ pub struct FnParser<I, F>(F, PhantomData<fn(I) -> I>);
/// extern crate combine;
/// # use combine::*;
/// # use combine::char::digit;
/// # use combine::primitives::{Consumed, Error};
/// # use combine::primitives::{Consumed, ParseError, StreamingError, SimpleStream};
/// # fn main() {
/// let mut even_digit = parser(|input| {
/// // Help type inference out
/// let _: &str = input;
/// let _: SimpleStream<&str> = input;
/// let position = input.position();
/// let (char_digit, input) = try!(digit().parse_stream(input));
/// let d = (char_digit as i32) - ('0' as i32);
Expand All @@ -1700,13 +1700,13 @@ pub struct FnParser<I, F>(F, PhantomData<fn(I) -> I>);
/// //Return an empty error since we only tested the first token of the stream
/// let errors = ParseError::new(
/// position,
/// <Self::Input as StreamOnce>::Error::Expected(From::from("even number"))
/// StreamingError::expected(From::from("even number"))
/// );
/// Err(Consumed::Empty(errors.into()))
/// }
/// });
/// let result = even_digit
/// .parse("8")
/// .simple_parse("8")
/// .map(|x| x.0);
/// assert_eq!(result, Ok(8));
/// # }
Expand Down Expand Up @@ -2353,8 +2353,8 @@ where
I: Stream,
P: Parser<Input = I>,
F: FnMut(P::Output) -> Result<O, E>,
E: Into<<P::Input as StreamOnce>::Error>,
<P::Input as StreamOnce>::Error: ParsingError<I::Item, I::Range, I::Position>,
E: Into<<I::Error as ParsingError<I::Item, I::Range, I::Position>>::StreamError>,
I::Error: ParsingError<I::Item, I::Range, I::Position>,
{
type Input = P::Input;
type Output = O;
Expand All @@ -2365,15 +2365,13 @@ where
EmptyOk((o, input)) => match (self.1)(o) {
Ok(o) => EmptyOk((o, input)),
Err(err) => EmptyErr(
<Self::Input as StreamOnce>::Error::empty(position)
.merge(err.into())
.into(),
<Self::Input as StreamOnce>::Error::from_error(position, err.into()).into(),
),
},
ConsumedOk((o, input)) => match (self.1)(o) {
Ok(o) => ConsumedOk((o, input)),
Err(err) => ConsumedErr(
<Self::Input as StreamOnce>::Error::empty(position).merge(err.into()),
<Self::Input as StreamOnce>::Error::from_error(position, err.into()).into(),
),
},
EmptyErr(err) => EmptyErr(err),
Expand All @@ -2389,11 +2387,12 @@ where
///
/// [`p.and_then(f)`]: ../primitives/trait.Parser.html#method.and_then
#[inline(always)]
pub fn and_then<P, F, O, E>(p: P, f: F) -> AndThen<P, F>
pub fn and_then<P, F, O, E, I>(p: P, f: F) -> AndThen<P, F>
where
P: Parser,
P: Parser<Input = I>,
F: FnMut(P::Output) -> Result<O, E>,
E: Into<<P::Input as StreamOnce>::Error>,
I: Stream,
E: Into<<I::Error as ParsingError<I::Item, I::Range, I::Position>>::StreamError>,
{
AndThen(p, f)
}
Expand Down Expand Up @@ -2463,7 +2462,7 @@ macro_rules! tuple_parser {
}
EmptyErr(mut err) => {
if first_empty_parser != 0 {
if let Ok(t) = input.uncons() {
if let Ok(t) = input.uncons::<UnexpectedParse>() {
err.error.add(StreamingError::unexpected_token(t));
}
add_error!(err);
Expand Down Expand Up @@ -2686,7 +2685,8 @@ where
/// struct Interner(HashMap<String, u32>);
/// impl Interner {
/// fn string<I>(&self, input: I) -> ParseResult<u32, I>
/// where I: Stream<Item=char>
/// where I: Stream<Item=char>,
/// I::Error: ParsingError<I::Item, I::Range, I::Position>,
/// {
/// many(letter())
/// .map(|s: String| self.0.get(&s).cloned().unwrap_or(0))
Expand Down
41 changes: 27 additions & 14 deletions src/lib.rs
Expand Up @@ -29,7 +29,7 @@
//! fn main() {
//! // Wrapping a `&str` with `State` provides automatic line and column tracking. If `State`
//! // was not used the positions would instead only be pointers into the `&str`
//! if let Err(err) = digit().or(letter()).parse(State::new("|")) {
//! if let Err(err) = digit().or(letter()).simple_parse(State::new("|")) {
//! assert_eq!(MSG, format!("{}", err));
//! }
//! }
Expand Down Expand Up @@ -70,7 +70,8 @@
//!
//! //Call parse with the input to execute the parser
//! let input = "1234, 45,78";
//! let result: Result<(Vec<i32>, &str), StreamError<&str>> = integer_list.parse(input);
//! let result: Result<(Vec<i32>, &str), StreamError<&str>> =
//! integer_list.simple_parse(input);
//! match result {
//! Ok((value, _remaining_input)) => println!("{:?}", value),
//! Err(err) => println!("{}", err)
Expand Down Expand Up @@ -216,10 +217,16 @@ macro_rules! impl_token_parser {
/// extern crate combine;
/// use combine::char::digit;
/// use combine::{any, choice, many1, Parser, Stream};
/// use combine::primitives::ParsingError;
///
/// parser!{
/// fn integer[I]()(I) -> i32
/// where [I: Stream<Item = char>]
/// where [
/// I: Stream<Item = char>,
/// I::Error: ParsingError<char, I::Range, I::Position>,
/// <I::Error as ParsingError<I::Item, I::Range, I::Position>>::StreamError:
/// From<::std::num::ParseIntError>,
/// ]
/// {
/// // The body must be a block body ( `{ <block body> }`) which ends with an expression
/// // which evaluates to a parser
Expand All @@ -239,7 +246,12 @@ macro_rules! impl_token_parser {
///
/// /// Parses an integer or a string (any characters)
/// pub fn integer_or_string[I]()(I) -> IntOrString
/// where [I: Stream<Item = char>]
/// where [
/// I: Stream<Item = char>,
/// I::Error: ParsingError<char, I::Range, I::Position>,
/// <I::Error as ParsingError<I::Item, I::Range, I::Position>>::StreamError:
/// From<::std::num::ParseIntError>,
/// ]
/// {
/// choice!(
/// integer().map(IntOrString::Int),
Expand All @@ -261,12 +273,15 @@ macro_rules! impl_token_parser {
/// }
///
/// fn main() {
/// assert_eq!(integer().parse("123"), Ok((123, "")));
/// assert!(integer().parse("!").is_err());
/// assert_eq!(integer().simple_parse("123"), Ok((123, "")));
/// assert!(integer().simple_parse("!").is_err());
///
/// assert_eq!(integer_or_string().parse("123"), Ok((IntOrString::Int(123), "")));
/// assert_eq!(
/// integer_or_string().parse("abc"),
/// integer_or_string().simple_parse("123"),
/// Ok((IntOrString::Int(123), ""))
/// );
/// assert_eq!(
/// integer_or_string().simple_parse("abc"),
/// Ok((IntOrString::String("abc".to_string()), ""))
/// );
/// assert_eq!(twice(|| digit()).parse("123"), Ok((('1', '2'), "3")));
Expand Down Expand Up @@ -598,7 +613,7 @@ mod tests {
fn iterator() {
let result = parser(integer)
.parse(State::new(IteratorStream::new("123".chars())))
.map(|(i, mut input)| (i, input.uncons().is_err()));
.map(|(i, mut input)| (i, input.uncons::<Error<_, _>>().is_err()));
assert_eq!(result, Ok((123i64, true)));
}
#[test]
Expand Down Expand Up @@ -724,7 +739,7 @@ mod tests {
I: Stream<Item = char, Error = StreamError<I>>,
I::Position: Default,
{
match input.clone().uncons() {
match input.clone().uncons::<Error<_, _>>() {
Ok(c) => if c.is_alphanumeric() {
let e = Error::Unexpected(c.into());
Err(Consumed::Empty(ParseError::new(input.position(), e).into()))
Expand Down Expand Up @@ -828,10 +843,8 @@ mod tests {
"error"
}
}
let result: Result<((), _), ParseError<_, char, &str>> = Parser::simple_parse(
&mut string("abc").and_then(|_| Err(ParseError::new(Default::default(), Error.into()))),
"abc",
);
let result: Result<((), _), ParseError<_, char, &str>> =
Parser::simple_parse(&mut string("abc").and_then(|_| Err(Error)), "abc");
assert!(result.is_err());
// Test that ParseError can be coerced to a StdError
let _ = result.map_err(|err| {
Expand Down

0 comments on commit bee8f9c

Please sign in to comment.