//! Basic types to build the parsers
//use self::IResult::*;
use *;
use Context;
use Context;
/// Holds the result of parsing functions
///
/// It depends on I, the input type, O, the output type, and E, the error type (by default u32)
///
/// The `Ok` side is an enum 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 = u32> = ;
/// Contains information on needed data if a parser returned `Incomplete`
/// The `Err` enum indicates the parser was not successful, and has three cases:
///
/// * `Incomplete` indicates that more data is needed to decide. The `Needed` enum
/// can contain how many additional bytes are necessary. If you are sure your parser
/// is working on full data, you can wrap your parser with the `complete` combinator
/// to transform that case in `Error`
/// * `Error` means some parser did not succeed, but another one might (as an example,
/// when testing different branches of an `alt` combinator)
/// * `Failure` indicates an unrecoverable error. As an example, if you recognize a prefix
/// to decide on the next parser to apply, and that parser fails, you know there's no need
/// to try other parsers, you were already in the right branch, so the data is invalid
///
/// Depending on a compilation flag, the content of the `Context` enum
/// can change. In the default case, it will only have one variant:
/// `Context::Code(I, ErrorKind<E=u32>)` (with `I` and `E` configurable).
/// It contains an error code and the input position that triggered it.
///
/// If you activate the `verbose-errors` compilation flags, it will add another
/// variant to the enum: `Context::List(Vec<(I, ErrorKind<E>)>)`.
/// This variant aggregates positions and error codes as the code backtracks
/// through the nested parsers.
/// The verbose errors feature allows for very flexible error management:
/// you can know precisely which parser got to which part of the input.
/// The main drawback is that it is a lot slower than default error
/// management.
use Convert;
/*
#[cfg(feature = "verbose-errors")]
/// This is the same as IResult, but without Done
///
/// This is used as the Error type when converting to std::result::Result
#[derive(Debug,PartialEq,Eq,Clone)]
pub enum IError<I,E=u32> {
Error(Err<I,E>),
Incomplete(Needed)
}
#[cfg(not(feature = "verbose-errors"))]
/// This is the same as IResult, but without Done
///
/// This is used as the Error type when converting to std::result::Result
#[derive(Debug,PartialEq,Eq,Clone)]
pub enum IError<E=u32> {
Error(Err<E>),
Incomplete(Needed)
}
impl<I,O,E> IResult<I,O,E> {
pub fn is_done(&self) -> bool {
match *self {
Done(_,_) => true,
_ => false
}
}
pub fn is_err(&self) -> bool {
match *self {
Error(_) => true,
_ => false
}
}
pub fn is_incomplete(&self) -> bool {
match *self {
Incomplete(_) => true,
_ => false
}
}
pub fn or(self, other: IResult<I, O, E>) -> IResult<I, O, E> {
if self.is_done() {
self
} else {
other
}
}
/// Maps a `IResult<I, O, E>` to `IResult<I, N, E>` by appling a function
/// to a contained `Done` value, leaving `Error` and `Incomplete` value
/// untouched.
#[inline]
pub fn map<N, F: FnOnce(O) -> N>(self, f: F) -> IResult<I, N, E> {
match self {
Done(i, o) => Done(i, f(o)),
Error(e) => Error(e),
Incomplete(n) => Incomplete(n),
}
}
/// Maps a `IResult<I, O, E>` to `IResult<I, O, E>` by appling a function
/// to a contained `Incomplete` value, leaving `Done` and `Error` value
/// untouched.
#[inline]
pub fn map_inc<F>(self, f: F) -> IResult<I, O, E>
where F: FnOnce(Needed) -> Needed {
match self {
Error(e) => Error(e),
Incomplete(n) => Incomplete(f(n)),
Done(i, o) => Done(i, o),
}
}
/// Unwrap the contained `Done(I, O)` value, or panic if the `IResult` is not
/// `Done`.
pub fn unwrap(self) -> (I, O) {
match self {
Done(i, o) => (i, o),
Incomplete(_) => panic!("unwrap() called on an IResult that is Incomplete"),
Error(_) => panic!("unwrap() called on an IResult that is Error")
}
}
/// Unwrap the contained `Done(I, O)` value or a default if the `IResult` is not
/// `Done`.
pub fn unwrap_or(self, default: (I, O)) -> (I, O) {
match self {
Done(i, o) => (i, o),
Incomplete(_) => default,
Error(_) => default
}
}
/// Unwrap the contained `Incomplete(n)` value, or panic if the `IResult` is not
/// `Incomplete`.
pub fn unwrap_inc(self) -> Needed {
match self {
Incomplete(n) => n,
Done(_, _) => panic!("unwrap_inc() called on an IResult that is Done"),
Error(_) => panic!("unwrap_inc() called on an IResult that is Error")
}
}
}
pub trait GetInput<I> {
fn remaining_input(&self) -> Option<I>;
}
pub trait GetOutput<O> {
fn output(&self) -> Option<O>;
}
impl<'a,I,O,E> GetInput<&'a[I]> for IResult<&'a[I],O,E> {
fn remaining_input(&self) -> Option<&'a[I]> {
match *self {
Done(ref i,_) => Some(*i),
_ => None
}
}
}
impl<O,E> GetInput<()> for IResult<(),O,E> {
fn remaining_input(&self) -> Option<()> {
match *self {
Done((),_) => Some(()),
_ => None
}
}
}
impl<'a,O,E> GetInput<&'a str> for IResult<&'a str,O,E> {
fn remaining_input(&self) -> Option<&'a str> {
match *self {
Done(ref i,_) => Some(*i),
_ => None
}
}
}
impl<'a,I,O,E> GetOutput<&'a[O]> for IResult<I,&'a[O],E> {
fn output(&self) -> Option<&'a[O]> {
match *self {
Done(_, ref o) => Some(*o),
_ => None
}
}
}
impl<I,E> GetOutput<()> for IResult<I,(),E> {
fn output(&self) -> Option<()> {
match *self {
Done(_,()) => Some(()),
_ => None
}
}
}
impl<'a,I,E> GetOutput<&'a str> for IResult<I,&'a str,E> {
fn output(&self) -> Option<&'a str> {
match *self {
Done(_,ref o) => Some(*o),
_ => None
}
}
}*/
/// creates a parse error from a `nom::ErrorKind`
/// and the position in the input
/// if "verbose-errors" is not activated,
/// it default to only the error code
;
/// creates a parse error from a `nom::ErrorKind`
/// and the position in the input
/// if "verbose-errors" is not activated,
/// it default to only the error code
;
/// creates a parse error from a `nom::ErrorKind`,
/// the position in the input and the next error in
/// the parsing tree.
/// if "verbose-errors" is not activated,
/// it default to only the error code
;
/// creates a parse error from a `nom::ErrorKind`,
/// the position in the input and the next error in
/// the parsing tree.
/// if "verbose-errors" is not activated,
/// it default to only the error code
;