1 //! Parsers constructor from regular functions
2 
3 use crate::{
4     error::{ParseResult, StdParseResult},
5     lib::marker::PhantomData,
6     stream::Stream,
7     Parser,
8 };
9 
10 impl<'a, Input: Stream, O> Parser<Input>
11     for dyn FnMut(&mut Input) -> StdParseResult<O, Input> + 'a
12 {
13     type Output = O;
14     type PartialState = ();
15 
16     #[inline]
parse_lazy(&mut self, input: &mut Input) -> ParseResult<O, Input::Error>17     fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<O, Input::Error> {
18         self(input).into()
19     }
20 }
21 
22 #[derive(Copy, Clone)]
23 pub struct FnParser<Input, F>(F, PhantomData<fn(Input) -> Input>);
24 
25 /// Wraps a function, turning it into a parser.
26 ///
27 /// Mainly needed to turn closures into parsers as function types can be casted to function pointers
28 /// to make them usable as a parser.
29 ///
30 /// ```
31 /// extern crate combine;
32 /// # use combine::*;
33 /// # use combine::parser::char::digit;
34 /// # use combine::error::{Commit, StreamError};
35 /// # use combine::stream::easy;
36 /// # fn main() {
37 /// let mut even_digit = parser(|input| {
38 ///     // Help type inference out
39 ///     let _: &mut easy::Stream<&str> = input;
40 ///     let position = input.position();
41 ///     let (char_digit, committed) = digit().parse_stream(input).into_result()?;
42 ///     let d = (char_digit as i32) - ('0' as i32);
43 ///     if d % 2 == 0 {
44 ///         Ok((d, committed))
45 ///     }
46 ///     else {
47 ///         //Return an empty error since we only tested the first token of the stream
48 ///         let errors = easy::Errors::new(
49 ///             position,
50 ///             StreamError::expected("even number")
51 ///         );
52 ///         Err(Commit::Peek(errors.into()))
53 ///     }
54 /// });
55 /// let result = even_digit
56 ///     .easy_parse("8")
57 ///     .map(|x| x.0);
58 /// assert_eq!(result, Ok(8));
59 /// # }
60 /// ```
parser<Input, O, F>(f: F) -> FnParser<Input, F> where Input: Stream, F: FnMut(&mut Input) -> StdParseResult<O, Input>,61 pub fn parser<Input, O, F>(f: F) -> FnParser<Input, F>
62 where
63     Input: Stream,
64     F: FnMut(&mut Input) -> StdParseResult<O, Input>,
65 {
66     FnParser(f, PhantomData)
67 }
68 
69 impl<Input, O, F> Parser<Input> for FnParser<Input, F>
70 where
71     Input: Stream,
72     F: FnMut(&mut Input) -> StdParseResult<O, Input>,
73 {
74     type Output = O;
75     type PartialState = ();
76 
77     #[inline]
parse_lazy(&mut self, input: &mut Input) -> ParseResult<O, Input::Error>78     fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<O, Input::Error> {
79         (self.0)(input).into()
80     }
81 }
82 
83 impl<Input, O> Parser<Input> for fn(&mut Input) -> StdParseResult<O, Input>
84 where
85     Input: Stream,
86 {
87     type Output = O;
88     type PartialState = ();
89 
90     #[inline]
parse_lazy(&mut self, input: &mut Input) -> ParseResult<O, Input::Error>91     fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<O, Input::Error> {
92         self(input).into()
93     }
94 }
95 
96 #[derive(Copy)]
97 pub struct EnvParser<E, Input, T>
98 where
99     Input: Stream,
100 {
101     env: E,
102     parser: fn(E, &mut Input) -> StdParseResult<T, Input>,
103 }
104 
105 impl<E, Input, T> Clone for EnvParser<E, Input, T>
106 where
107     Input: Stream,
108     E: Clone,
109 {
clone(&self) -> Self110     fn clone(&self) -> Self {
111         EnvParser {
112             env: self.env.clone(),
113             parser: self.parser,
114         }
115     }
116 }
117 
118 impl<Input, E, O> Parser<Input> for EnvParser<E, Input, O>
119 where
120     E: Clone,
121     Input: Stream,
122 {
123     type Output = O;
124     type PartialState = ();
125 
126     #[inline]
parse_lazy(&mut self, input: &mut Input) -> ParseResult<O, Input::Error>127     fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<O, Input::Error> {
128         (self.parser)(self.env.clone(), input).into()
129     }
130 }
131 
132 /// Constructs a parser out of an environment and a function which needs the given environment to
133 /// do the parsing. This is commonly useful to allow multiple parsers to share some environment
134 /// while still allowing the parsers to be written in separate functions.
135 ///
136 /// ```
137 /// # extern crate combine;
138 /// # use std::collections::HashMap;
139 /// # use combine::*;
140 /// # use combine::parser::function::env_parser;
141 /// # use combine::parser::char::letter;
142 /// # fn main() {
143 /// struct Interner(HashMap<String, u32>);
144 /// impl Interner {
145 ///     fn string<Input>(&self, input: &mut Input) -> StdParseResult<u32, Input>
146 ///         where Input: Stream<Token = char>,
147 ///     {
148 ///         many(letter())
149 ///             .map(|s: String| self.0.get(&s).cloned().unwrap_or(0))
150 ///             .parse_stream(input)
151 ///             .into_result()
152 ///     }
153 /// }
154 ///
155 /// let mut map = HashMap::new();
156 /// map.insert("hello".into(), 1);
157 /// map.insert("test".into(), 2);
158 ///
159 /// let env = Interner(map);
160 /// let mut parser = env_parser(&env, Interner::string);
161 ///
162 /// let result = parser.parse("hello");
163 /// assert_eq!(result, Ok((1, "")));
164 ///
165 /// let result = parser.parse("world");
166 /// assert_eq!(result, Ok((0, "")));
167 /// # }
168 /// ```
env_parser<E, Input, O>( env: E, parser: fn(E, &mut Input) -> StdParseResult<O, Input>, ) -> EnvParser<E, Input, O> where E: Clone, Input: Stream,169 pub fn env_parser<E, Input, O>(
170     env: E,
171     parser: fn(E, &mut Input) -> StdParseResult<O, Input>,
172 ) -> EnvParser<E, Input, O>
173 where
174     E: Clone,
175     Input: Stream,
176 {
177     EnvParser { env, parser }
178 }
179