1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
//! Basic types to build the parsers use self::IResult::*; use util::ErrorKind; #[cfg(feature = "core")] use std::prelude::v1::*; use std::boxed::Box; /* /// (Experimental) Closure used to hold the temporary state of resumable parsing pub type IResultClosure<'a,I,O> = Box<FnMut(I) -> IResult<I,O> +'a>; //cf libcore/fmt/mod.rs:674 impl<'a,I,O> Debug for IResultClosure<'a,I,O> { fn fmt(&self, f: &mut Formatter) -> Result { Display::fmt("closure", f) } } impl<'a,I:PartialEq,O:PartialEq> PartialEq for IResultClosure<'a,I,O> { #[allow(unused_variables)] fn eq<'b>(&self, other: &IResultClosure<'b,I,O>) -> bool { false } #[allow(unused_variables)] fn ne<'b>(&self, other: &IResultClosure<'b,I,O>) -> bool { false } } impl<'a,I:Eq,O:Eq> Eq for IResultClosure<'a,I,O> {} */ //type IResultClosure<'a,I,O> = |I|:'a -> IResult<'a,I,O>; //type IResultClosure<'a,I,O> = Fn<I, IResult<'a,I,O>>; /// Contains the error that a parser can return /// /// It can represent a linked list of errors, indicating the path taken in the parsing tree, with corresponding position in the input data. /// It depends on P, the input position (for a &[u8] parser, it would be a &[u8]), and E, the custom error type (by default, u32) #[derive(Debug,PartialEq,Eq,Clone)] pub enum Err<P,E=u32>{ /// An error code, represented by an ErrorKind, which can contain a custom error code represented by E Code(ErrorKind<E>), /// An error code, and the next error Node(ErrorKind<E>, Box<Err<P,E>>), /// An error code, and the input position Position(ErrorKind<E>, P), /// An error code, the input position and the next error NodePosition(ErrorKind<E>, P, Box<Err<P,E>>) } /// Contains information on needed data if a parser returned `Incomplete` #[derive(Debug,PartialEq,Eq,Clone,Copy)] pub enum Needed { /// needs more data, but we do not know how much Unknown, /// contains the required data size Size(usize) } /// 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) /// #[derive(Debug,PartialEq,Eq,Clone)] pub enum IResult<I,O,E=u32> { /// indicates a correct parsing, the first field containing the rest of the unparsed data, the second field contains the parsed data Done(I,O), /// contains a Err, an enum that can indicate an error code, a position in the input, and a pointer to another error, making a list of errors in the parsing tree Error(Err<I,E>), //Incomplete(proc(I):'a -> IResult<I,O>) /// Incomplete contains a Needed, an enum than can represent a known quantity of input data, or unknown Incomplete(Needed) //Incomplete(Box<FnMut(I) -> IResult<I,O>>) //Incomplete(IResultClosure<I,O>) //Incomplete(|I|:'a -> IResult<'a,I,O>) //Incomplete(fn(I) -> IResult<'a,I,O>) } impl<I,O> IResult<I,O> { 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 trait GetInput<I> { fn remaining_input(&self) -> Option<I>; } pub trait GetOutput<O> { fn output(&self) -> Option<O>; } impl<'a,I,O> GetInput<&'a[I]> for IResult<&'a[I],O> { fn remaining_input(&self) -> Option<&'a[I]> { match *self { Done(ref i,_) => Some(*i), _ => None } } } impl<'a,O> GetInput<()> for IResult<(),O> { fn remaining_input(&self) -> Option<()> { match *self { Done((),_) => Some(()), _ => None } } } impl<'a,I,O> GetOutput<&'a[O]> for IResult<I,&'a[O]> { fn output(&self) -> Option<&'a[O]> { match *self { Done(_, ref o) => Some(*o), _ => None } } } impl<'a,I> GetOutput<()> for IResult<I,()> { fn output(&self) -> Option<()> { match *self { Done(_,()) => Some(()), _ => None } } }