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 149
//! Basic types to build the parsers use self::IResult::*; #[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 #[derive(Debug,PartialEq,Eq,Clone)] pub enum Err<'a>{ /// an error code Code(u32), /// an error code, and the next error in the parsing chain Node(u32, Box<Err<'a>>), /// an error code and the related input position Position(u32, &'a [u8]), /// an error code, the related input position, and the next error in the parsing chain NodePosition(u32, &'a [u8], Box<Err<'a>>) } /// Contains information on needed data if a parser returned `Incomplete` #[derive(Debug,PartialEq,Eq,Clone)] 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 types, and O, the output type. /// /// * Done indicates a correct parsing, the first field containing the rest of the unparsed data, /// the second field contains the parsed data /// /// * Error is currently a u32, but should be updated to indicate which parser had a problem, /// a description, and an eventual stack of parser to know which path failed /// /// * Incomplete will hold the closure used to restart the computation once more data is available. /// Current attemps at implementation of Incomplete are progressing, but slowed down by lifetime problems #[derive(Debug,PartialEq,Eq,Clone)] pub enum IResult<'a,I,O> { Done(I,O), Error(Err<'a>), //Incomplete(proc(I):'a -> IResult<I,O>) 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<'a,I,O> IResult<'a,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,&'a[I],O> { fn remaining_input(&self) -> Option<&'a[I]> { match self { &Done(ref i,_) => Some(*i), _ => None } } } impl<'a,O> GetInput<()> for IResult<'a,(),O> { fn remaining_input(&self) -> Option<()> { match self { &Done((),_) => Some(()), _ => None } } } impl<'a,I,O> GetOutput<&'a[O]> for IResult<'a,I,&'a[O]> { fn output(&self) -> Option<&'a[O]> { match self { &Done(_, ref o) => Some(*o), _ => None } } } impl<'a,I> GetOutput<()> for IResult<'a,I,()> { fn output(&self) -> Option<()> { match self { &Done(_,()) => Some(()), _ => None } } }