/rust/registry/src/index.crates.io-1949cf8c6b5b557f/combine-4.6.7/src/parser/repeat.rs
Line | Count | Source |
1 | | //! Combinators which take one or more parsers and applies them repeatedly. |
2 | | |
3 | | use crate::{ |
4 | | error::{ |
5 | | Commit, ParseError, |
6 | | ParseResult::{self, *}, |
7 | | ResultExt, StdParseResult, StreamError, Tracked, |
8 | | }, |
9 | | lib::{borrow::BorrowMut, cmp, marker::PhantomData, mem}, |
10 | | parser::{ |
11 | | choice::{optional, Optional, Or}, |
12 | | combinator::{ignore, Ignore}, |
13 | | function::{parser, FnParser}, |
14 | | sequence::With, |
15 | | token::{value, Value}, |
16 | | FirstMode, ParseMode, |
17 | | }, |
18 | | stream::{uncons, Stream, StreamOnce}, |
19 | | ErrorOffset, Parser, |
20 | | }; |
21 | | |
22 | | parser! { |
23 | | pub struct Count; |
24 | | |
25 | | /// Parses `parser` from zero up to `count` times. |
26 | | /// |
27 | | /// ``` |
28 | | /// # extern crate combine; |
29 | | /// # use combine::*; |
30 | | /// # use combine::error::Info; |
31 | | /// # use combine::stream::easy::Error; |
32 | | /// # fn main() { |
33 | | /// let mut parser = count(2, token(b'a')); |
34 | | /// |
35 | | /// let result = parser.parse(&b"aaab"[..]); |
36 | | /// assert_eq!(result, Ok((b"aa"[..].to_owned(), &b"ab"[..]))); |
37 | | /// # } |
38 | | /// ``` |
39 | | pub fn count[F, Input, P](count: usize, parser: P)(Input) -> F |
40 | | where [ |
41 | | Input: Stream, |
42 | | P: Parser<Input>, |
43 | | F: Extend<P::Output> + Default, |
44 | | ] |
45 | | { |
46 | | count_min_max(0, *count, parser) |
47 | | } |
48 | | } |
49 | | |
50 | | parser! { |
51 | | pub struct SkipCount; |
52 | | type PartialState = <With<Count<Sink, Input, P>, Value<Input, ()>> as Parser<Input>>::PartialState; |
53 | | /// Parses `parser` from zero up to `count` times skipping the output of `parser`. |
54 | | /// |
55 | | /// ``` |
56 | | /// # extern crate combine; |
57 | | /// # use combine::*; |
58 | | /// # use combine::stream::easy::{Error, Info}; |
59 | | /// # fn main() { |
60 | | /// let mut parser = skip_count(2, token(b'a')); |
61 | | /// |
62 | | /// let result = parser.parse(&b"aaab"[..]); |
63 | | /// assert_eq!(result, Ok(((), &b"ab"[..]))); |
64 | | /// # } |
65 | | /// ``` |
66 | | pub fn skip_count[Input, P](count: usize, parser: P)(Input) -> () |
67 | | where [ |
68 | | P: Parser<Input> |
69 | | ] |
70 | | { |
71 | | self::count::<Sink, _, _>(*count, parser.map(|_| ())).with(value(())) |
72 | | } |
73 | | } |
74 | | |
75 | | #[derive(Copy, Clone)] |
76 | | pub struct CountMinMax<F, P> { |
77 | | parser: P, |
78 | | min: usize, |
79 | | max: usize, |
80 | | _marker: PhantomData<fn() -> F>, |
81 | | } |
82 | | |
83 | | struct SuggestSizeHint<I> { |
84 | | iterator: I, |
85 | | min: usize, |
86 | | max: Option<usize>, |
87 | | } |
88 | | |
89 | | impl<I> Iterator for SuggestSizeHint<I> |
90 | | where |
91 | | I: Iterator, |
92 | | { |
93 | | type Item = I::Item; |
94 | | |
95 | | #[inline] |
96 | 5.92M | fn next(&mut self) -> Option<Self::Item> { |
97 | 5.92M | self.iterator.next() |
98 | 5.92M | } <combine::parser::repeat::SuggestSizeHint<core::iter::adapters::inspect::Inspect<core::iter::adapters::take::Take<&mut combine::parser::repeat::Iter<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, &mut combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>, &mut combine::parser::combinator::AnySendSyncPartialState, combine::parser::PartialMode>>, <combine::parser::repeat::CountMinMax<alloc::vec::Vec<redis::types::Value>, combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>> as combine::parser::Parser<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>>::parse_mode_impl<combine::parser::PartialMode>::{closure#0}>> as core::iter::traits::iterator::Iterator>::nextLine | Count | Source | 96 | 5.03M | fn next(&mut self) -> Option<Self::Item> { | 97 | 5.03M | self.iterator.next() | 98 | 5.03M | } |
<combine::parser::repeat::SuggestSizeHint<core::iter::adapters::inspect::Inspect<core::iter::adapters::take::Take<&mut combine::parser::repeat::Iter<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, &mut combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>, &mut combine::parser::combinator::AnySendSyncPartialState, combine::parser::FirstMode>>, <combine::parser::repeat::CountMinMax<alloc::vec::Vec<redis::types::Value>, combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>> as combine::parser::Parser<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>>::parse_mode_impl<combine::parser::FirstMode>::{closure#0}>> as core::iter::traits::iterator::Iterator>::nextLine | Count | Source | 96 | 883k | fn next(&mut self) -> Option<Self::Item> { | 97 | 883k | self.iterator.next() | 98 | 883k | } |
Unexecuted instantiation: <combine::parser::repeat::SuggestSizeHint<_> as core::iter::traits::iterator::Iterator>::next |
99 | | |
100 | | #[inline] |
101 | 125k | fn size_hint(&self) -> (usize, Option<usize>) { |
102 | 125k | (self.min, self.max) |
103 | 125k | } <combine::parser::repeat::SuggestSizeHint<core::iter::adapters::inspect::Inspect<core::iter::adapters::take::Take<&mut combine::parser::repeat::Iter<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, &mut combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>, &mut combine::parser::combinator::AnySendSyncPartialState, combine::parser::PartialMode>>, <combine::parser::repeat::CountMinMax<alloc::vec::Vec<redis::types::Value>, combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>> as combine::parser::Parser<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>>::parse_mode_impl<combine::parser::PartialMode>::{closure#0}>> as core::iter::traits::iterator::Iterator>::size_hintLine | Count | Source | 101 | 7.58k | fn size_hint(&self) -> (usize, Option<usize>) { | 102 | 7.58k | (self.min, self.max) | 103 | 7.58k | } |
<combine::parser::repeat::SuggestSizeHint<core::iter::adapters::inspect::Inspect<core::iter::adapters::take::Take<&mut combine::parser::repeat::Iter<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, &mut combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>, &mut combine::parser::combinator::AnySendSyncPartialState, combine::parser::FirstMode>>, <combine::parser::repeat::CountMinMax<alloc::vec::Vec<redis::types::Value>, combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>> as combine::parser::Parser<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>>::parse_mode_impl<combine::parser::FirstMode>::{closure#0}>> as core::iter::traits::iterator::Iterator>::size_hintLine | Count | Source | 101 | 118k | fn size_hint(&self) -> (usize, Option<usize>) { | 102 | 118k | (self.min, self.max) | 103 | 118k | } |
Unexecuted instantiation: <combine::parser::repeat::SuggestSizeHint<_> as core::iter::traits::iterator::Iterator>::size_hint |
104 | | } |
105 | | |
106 | 533k | fn suggest_size_hint<I>(iterator: I, (min, max): (usize, Option<usize>)) -> SuggestSizeHint<I> |
107 | 533k | where |
108 | 533k | I: Iterator, |
109 | | { |
110 | 533k | SuggestSizeHint { |
111 | 533k | iterator, |
112 | 533k | // Invalid input may report an extreme size so we guard against that (while still |
113 | 533k | // optimizing by preallocating for the expected case of success) |
114 | 533k | min: cmp::min(min, 4096), |
115 | 533k | max, |
116 | 533k | } |
117 | 533k | } combine::parser::repeat::suggest_size_hint::<core::iter::adapters::inspect::Inspect<core::iter::adapters::take::Take<&mut combine::parser::repeat::Iter<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, &mut combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>, &mut combine::parser::combinator::AnySendSyncPartialState, combine::parser::PartialMode>>, <combine::parser::repeat::CountMinMax<alloc::vec::Vec<redis::types::Value>, combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>> as combine::parser::Parser<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>>::parse_mode_impl<combine::parser::PartialMode>::{closure#0}>>Line | Count | Source | 106 | 379k | fn suggest_size_hint<I>(iterator: I, (min, max): (usize, Option<usize>)) -> SuggestSizeHint<I> | 107 | 379k | where | 108 | 379k | I: Iterator, | 109 | | { | 110 | 379k | SuggestSizeHint { | 111 | 379k | iterator, | 112 | 379k | // Invalid input may report an extreme size so we guard against that (while still | 113 | 379k | // optimizing by preallocating for the expected case of success) | 114 | 379k | min: cmp::min(min, 4096), | 115 | 379k | max, | 116 | 379k | } | 117 | 379k | } |
combine::parser::repeat::suggest_size_hint::<core::iter::adapters::inspect::Inspect<core::iter::adapters::take::Take<&mut combine::parser::repeat::Iter<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, &mut combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>, &mut combine::parser::combinator::AnySendSyncPartialState, combine::parser::FirstMode>>, <combine::parser::repeat::CountMinMax<alloc::vec::Vec<redis::types::Value>, combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>> as combine::parser::Parser<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>>::parse_mode_impl<combine::parser::FirstMode>::{closure#0}>>Line | Count | Source | 106 | 153k | fn suggest_size_hint<I>(iterator: I, (min, max): (usize, Option<usize>)) -> SuggestSizeHint<I> | 107 | 153k | where | 108 | 153k | I: Iterator, | 109 | | { | 110 | 153k | SuggestSizeHint { | 111 | 153k | iterator, | 112 | 153k | // Invalid input may report an extreme size so we guard against that (while still | 113 | 153k | // optimizing by preallocating for the expected case of success) | 114 | 153k | min: cmp::min(min, 4096), | 115 | 153k | max, | 116 | 153k | } | 117 | 153k | } |
Unexecuted instantiation: combine::parser::repeat::suggest_size_hint::<_> |
118 | | |
119 | | impl<Input, P, F> Parser<Input> for CountMinMax<F, P> |
120 | | where |
121 | | Input: Stream, |
122 | | P: Parser<Input>, |
123 | | F: Extend<P::Output> + Default, |
124 | | { |
125 | | type Output = F; |
126 | | type PartialState = (usize, F, P::PartialState); |
127 | | |
128 | | parse_mode!(Input); |
129 | | #[inline] |
130 | 533k | fn parse_mode_impl<M>( |
131 | 533k | &mut self, |
132 | 533k | mode: M, |
133 | 533k | input: &mut Input, |
134 | 533k | state: &mut Self::PartialState, |
135 | 533k | ) -> ParseResult<Self::Output, Input::Error> |
136 | 533k | where |
137 | 533k | M: ParseMode, |
138 | | { |
139 | 533k | let (count, elements, child_state) = state; |
140 | | |
141 | 533k | let mut iter = self.parser.by_ref().partial_iter(mode, input, child_state); |
142 | 533k | let remaining_min = self.min.saturating_sub(*count); |
143 | 533k | let remaining_max = self.max - *count; |
144 | 533k | elements.extend(suggest_size_hint( |
145 | 533k | iter.by_ref().take(remaining_max).inspect(|_| *count += 1), |
146 | 533k | (remaining_min, Some(remaining_max)), |
147 | | )); |
148 | 533k | if *count < self.min { |
149 | 398k | let err = StreamError::message_format(format_args!( |
150 | 398k | "expected {} more elements", |
151 | 398k | self.min - *count |
152 | | )); |
153 | 398k | iter.fail(err) |
154 | | } else { |
155 | 134k | iter.into_result_fast(elements).map(|x| { |
156 | 134k | *count = 0; |
157 | 134k | x |
158 | 134k | }) <combine::parser::repeat::CountMinMax<alloc::vec::Vec<redis::types::Value>, combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>> as combine::parser::Parser<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>>::parse_mode_impl::<combine::parser::PartialMode>::{closure#1}Line | Count | Source | 155 | 16.9k | iter.into_result_fast(elements).map(|x| { | 156 | 16.9k | *count = 0; | 157 | 16.9k | x | 158 | 16.9k | }) |
<combine::parser::repeat::CountMinMax<alloc::vec::Vec<redis::types::Value>, combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>> as combine::parser::Parser<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>>::parse_mode_impl::<combine::parser::FirstMode>::{closure#1}Line | Count | Source | 155 | 117k | iter.into_result_fast(elements).map(|x| { | 156 | 117k | *count = 0; | 157 | 117k | x | 158 | 117k | }) |
Unexecuted instantiation: <combine::parser::repeat::CountMinMax<_, _> as combine::parser::Parser<_>>::parse_mode_impl::<_>::{closure#1} |
159 | | } |
160 | 533k | } <combine::parser::repeat::CountMinMax<alloc::vec::Vec<redis::types::Value>, combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>> as combine::parser::Parser<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>>::parse_mode_impl::<combine::parser::PartialMode>Line | Count | Source | 130 | 379k | fn parse_mode_impl<M>( | 131 | 379k | &mut self, | 132 | 379k | mode: M, | 133 | 379k | input: &mut Input, | 134 | 379k | state: &mut Self::PartialState, | 135 | 379k | ) -> ParseResult<Self::Output, Input::Error> | 136 | 379k | where | 137 | 379k | M: ParseMode, | 138 | | { | 139 | 379k | let (count, elements, child_state) = state; | 140 | | | 141 | 379k | let mut iter = self.parser.by_ref().partial_iter(mode, input, child_state); | 142 | 379k | let remaining_min = self.min.saturating_sub(*count); | 143 | 379k | let remaining_max = self.max - *count; | 144 | 379k | elements.extend(suggest_size_hint( | 145 | 379k | iter.by_ref().take(remaining_max).inspect(|_| *count += 1), | 146 | 379k | (remaining_min, Some(remaining_max)), | 147 | | )); | 148 | 379k | if *count < self.min { | 149 | 362k | let err = StreamError::message_format(format_args!( | 150 | 362k | "expected {} more elements", | 151 | 362k | self.min - *count | 152 | | )); | 153 | 362k | iter.fail(err) | 154 | | } else { | 155 | 16.9k | iter.into_result_fast(elements).map(|x| { | 156 | | *count = 0; | 157 | | x | 158 | | }) | 159 | | } | 160 | 379k | } |
<combine::parser::repeat::CountMinMax<alloc::vec::Vec<redis::types::Value>, combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>> as combine::parser::Parser<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>>::parse_mode_impl::<combine::parser::FirstMode>Line | Count | Source | 130 | 153k | fn parse_mode_impl<M>( | 131 | 153k | &mut self, | 132 | 153k | mode: M, | 133 | 153k | input: &mut Input, | 134 | 153k | state: &mut Self::PartialState, | 135 | 153k | ) -> ParseResult<Self::Output, Input::Error> | 136 | 153k | where | 137 | 153k | M: ParseMode, | 138 | | { | 139 | 153k | let (count, elements, child_state) = state; | 140 | | | 141 | 153k | let mut iter = self.parser.by_ref().partial_iter(mode, input, child_state); | 142 | 153k | let remaining_min = self.min.saturating_sub(*count); | 143 | 153k | let remaining_max = self.max - *count; | 144 | 153k | elements.extend(suggest_size_hint( | 145 | 153k | iter.by_ref().take(remaining_max).inspect(|_| *count += 1), | 146 | 153k | (remaining_min, Some(remaining_max)), | 147 | | )); | 148 | 153k | if *count < self.min { | 149 | 35.9k | let err = StreamError::message_format(format_args!( | 150 | 35.9k | "expected {} more elements", | 151 | 35.9k | self.min - *count | 152 | | )); | 153 | 35.9k | iter.fail(err) | 154 | | } else { | 155 | 117k | iter.into_result_fast(elements).map(|x| { | 156 | | *count = 0; | 157 | | x | 158 | | }) | 159 | | } | 160 | 153k | } |
Unexecuted instantiation: <combine::parser::repeat::CountMinMax<_, _> as combine::parser::Parser<_>>::parse_mode_impl::<_> |
161 | | |
162 | 2.02k | fn add_error(&mut self, error: &mut Tracked<<Input as StreamOnce>::Error>) { |
163 | 2.02k | self.parser.add_error(error) |
164 | 2.02k | } <combine::parser::repeat::CountMinMax<alloc::vec::Vec<redis::types::Value>, combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>> as combine::parser::Parser<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>>::add_errorLine | Count | Source | 162 | 2.02k | fn add_error(&mut self, error: &mut Tracked<<Input as StreamOnce>::Error>) { | 163 | 2.02k | self.parser.add_error(error) | 164 | 2.02k | } |
Unexecuted instantiation: <combine::parser::repeat::CountMinMax<_, _> as combine::parser::Parser<_>>::add_error |
165 | | } |
166 | | |
167 | | /// Parses `parser` from `min` to `max` times (including `min` and `max`). |
168 | | /// |
169 | | /// ``` |
170 | | /// # extern crate combine; |
171 | | /// # use combine::*; |
172 | | /// # use combine::stream::easy::{Error, Info}; |
173 | | /// # fn main() { |
174 | | /// let mut parser = count_min_max(2, 2, token(b'a')); |
175 | | /// |
176 | | /// let result = parser.parse(&b"aaab"[..]); |
177 | | /// assert_eq!(result, Ok((b"aa"[..].to_owned(), &b"ab"[..]))); |
178 | | /// let result = parser.parse(&b"ab"[..]); |
179 | | /// assert!(result.is_err()); |
180 | | /// # } |
181 | | /// ``` |
182 | | /// |
183 | | /// # Panics |
184 | | /// |
185 | | /// If `min` > `max`. |
186 | 533k | pub fn count_min_max<F, Input, P>(min: usize, max: usize, parser: P) -> CountMinMax<F, P> |
187 | 533k | where |
188 | 533k | Input: Stream, |
189 | 533k | P: Parser<Input>, |
190 | 533k | F: Extend<P::Output> + Default, |
191 | | { |
192 | 533k | assert!(min <= max); |
193 | | |
194 | 533k | CountMinMax { |
195 | 533k | parser, |
196 | 533k | min, |
197 | 533k | max, |
198 | 533k | _marker: PhantomData, |
199 | 533k | } |
200 | 533k | } combine::parser::repeat::count_min_max::<alloc::vec::Vec<redis::types::Value>, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>>Line | Count | Source | 186 | 533k | pub fn count_min_max<F, Input, P>(min: usize, max: usize, parser: P) -> CountMinMax<F, P> | 187 | 533k | where | 188 | 533k | Input: Stream, | 189 | 533k | P: Parser<Input>, | 190 | 533k | F: Extend<P::Output> + Default, | 191 | | { | 192 | 533k | assert!(min <= max); | 193 | | | 194 | 533k | CountMinMax { | 195 | 533k | parser, | 196 | 533k | min, | 197 | 533k | max, | 198 | 533k | _marker: PhantomData, | 199 | 533k | } | 200 | 533k | } |
Unexecuted instantiation: combine::parser::repeat::count_min_max::<_, _, _> |
201 | | |
202 | | parser! { |
203 | | pub struct SkipCountMinMax; |
204 | | type PartialState = <With<CountMinMax<Sink, P>, Value<Input, ()>> as Parser<Input>>::PartialState; |
205 | | /// Parses `parser` from `min` to `max` times (including `min` and `max`) |
206 | | /// skipping the output of `parser`. |
207 | | /// |
208 | | /// ``` |
209 | | /// # extern crate combine; |
210 | | /// # use combine::*; |
211 | | /// # fn main() { |
212 | | /// let mut parser = skip_count_min_max(2, 2, token(b'a')); |
213 | | /// |
214 | | /// let result = parser.parse(&b"aaab"[..]); |
215 | | /// assert_eq!(result, Ok(((), &b"ab"[..]))); |
216 | | /// let result = parser.parse(&b"ab"[..]); |
217 | | /// assert!(result.is_err()); |
218 | | /// # } |
219 | | /// ``` |
220 | | /// |
221 | | /// # Panics |
222 | | /// |
223 | | /// If `min` > `max`. |
224 | | pub fn skip_count_min_max[Input, P](min: usize, max: usize, parser: P)(Input) -> () |
225 | | where [ |
226 | | P: Parser<Input>, |
227 | | ] |
228 | | { |
229 | | count_min_max::<Sink, _, _>(*min, *max, parser.map(|_| ())).with(value(())) |
230 | | } |
231 | | } |
232 | | |
233 | | pub struct Iter<'a, Input, P, S, M> |
234 | | where |
235 | | Input: Stream, |
236 | | P: Parser<Input>, |
237 | | { |
238 | | parser: P, |
239 | | input: &'a mut Input, |
240 | | committed: bool, |
241 | | state: State<<Input as StreamOnce>::Error>, |
242 | | partial_state: S, |
243 | | mode: M, |
244 | | } |
245 | | |
246 | | enum State<E> { |
247 | | Ok, |
248 | | PeekErr(E), |
249 | | CommitErr(E), |
250 | | } |
251 | | |
252 | | impl<'a, Input, P, S, M> Iter<'a, Input, P, S, M> |
253 | | where |
254 | | Input: Stream, |
255 | | P: Parser<Input>, |
256 | | S: BorrowMut<P::PartialState>, |
257 | | { |
258 | 533k | pub fn new(parser: P, mode: M, input: &'a mut Input, partial_state: S) -> Self { |
259 | 533k | Iter { |
260 | 533k | parser, |
261 | 533k | input, |
262 | 533k | committed: false, |
263 | 533k | state: State::Ok, |
264 | 533k | partial_state, |
265 | 533k | mode, |
266 | 533k | } |
267 | 533k | } <combine::parser::repeat::Iter<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, &mut combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>, &mut combine::parser::combinator::AnySendSyncPartialState, combine::parser::PartialMode>>::newLine | Count | Source | 258 | 379k | pub fn new(parser: P, mode: M, input: &'a mut Input, partial_state: S) -> Self { | 259 | 379k | Iter { | 260 | 379k | parser, | 261 | 379k | input, | 262 | 379k | committed: false, | 263 | 379k | state: State::Ok, | 264 | 379k | partial_state, | 265 | 379k | mode, | 266 | 379k | } | 267 | 379k | } |
<combine::parser::repeat::Iter<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, &mut combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>, &mut combine::parser::combinator::AnySendSyncPartialState, combine::parser::FirstMode>>::newLine | Count | Source | 258 | 153k | pub fn new(parser: P, mode: M, input: &'a mut Input, partial_state: S) -> Self { | 259 | 153k | Iter { | 260 | 153k | parser, | 261 | 153k | input, | 262 | 153k | committed: false, | 263 | 153k | state: State::Ok, | 264 | 153k | partial_state, | 265 | 153k | mode, | 266 | 153k | } | 267 | 153k | } |
Unexecuted instantiation: <combine::parser::repeat::Iter<_, _, _, _>>::new |
268 | | /// Converts the iterator to a `ParseResult`, returning `Ok` if the parsing so far has be done |
269 | | /// without any errors which committed data. |
270 | 0 | pub fn into_result<O>(self, value: O) -> StdParseResult<O, Input> { |
271 | 0 | self.into_result_(value).into() |
272 | 0 | } |
273 | | |
274 | 0 | fn into_result_<O>(self, value: O) -> ParseResult<O, Input::Error> { |
275 | 0 | match self.state { |
276 | | State::Ok | State::PeekErr(_) => { |
277 | 0 | if self.committed { |
278 | 0 | CommitOk(value) |
279 | | } else { |
280 | 0 | PeekOk(value) |
281 | | } |
282 | | } |
283 | 0 | State::CommitErr(e) => CommitErr(e), |
284 | | } |
285 | 0 | } |
286 | | |
287 | 134k | fn into_result_fast<O>(self, value: &mut O) -> ParseResult<O, Input::Error> |
288 | 134k | where |
289 | 134k | O: Default, |
290 | | { |
291 | 134k | match self.state { |
292 | | State::Ok | State::PeekErr(_) => { |
293 | 134k | let value = mem::take(value); |
294 | 134k | if self.committed { |
295 | 118k | CommitOk(value) |
296 | | } else { |
297 | 16.4k | PeekOk(value) |
298 | | } |
299 | | } |
300 | 0 | State::CommitErr(e) => CommitErr(e), |
301 | | } |
302 | 134k | } <combine::parser::repeat::Iter<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, &mut combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>, &mut combine::parser::combinator::AnySendSyncPartialState, combine::parser::PartialMode>>::into_result_fast::<alloc::vec::Vec<redis::types::Value>>Line | Count | Source | 287 | 16.9k | fn into_result_fast<O>(self, value: &mut O) -> ParseResult<O, Input::Error> | 288 | 16.9k | where | 289 | 16.9k | O: Default, | 290 | | { | 291 | 16.9k | match self.state { | 292 | | State::Ok | State::PeekErr(_) => { | 293 | 16.9k | let value = mem::take(value); | 294 | 16.9k | if self.committed { | 295 | 16.9k | CommitOk(value) | 296 | | } else { | 297 | 0 | PeekOk(value) | 298 | | } | 299 | | } | 300 | 0 | State::CommitErr(e) => CommitErr(e), | 301 | | } | 302 | 16.9k | } |
<combine::parser::repeat::Iter<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, &mut combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>, &mut combine::parser::combinator::AnySendSyncPartialState, combine::parser::FirstMode>>::into_result_fast::<alloc::vec::Vec<redis::types::Value>>Line | Count | Source | 287 | 117k | fn into_result_fast<O>(self, value: &mut O) -> ParseResult<O, Input::Error> | 288 | 117k | where | 289 | 117k | O: Default, | 290 | | { | 291 | 117k | match self.state { | 292 | | State::Ok | State::PeekErr(_) => { | 293 | 117k | let value = mem::take(value); | 294 | 117k | if self.committed { | 295 | 101k | CommitOk(value) | 296 | | } else { | 297 | 16.4k | PeekOk(value) | 298 | | } | 299 | | } | 300 | 0 | State::CommitErr(e) => CommitErr(e), | 301 | | } | 302 | 117k | } |
Unexecuted instantiation: <combine::parser::repeat::Iter<_, _, _, _>>::into_result_fast::<_> |
303 | | |
304 | 398k | fn fail<T>( |
305 | 398k | self, |
306 | 398k | err: <<Input as StreamOnce>::Error as ParseError< |
307 | 398k | <Input as StreamOnce>::Token, |
308 | 398k | <Input as StreamOnce>::Range, |
309 | 398k | <Input as StreamOnce>::Position, |
310 | 398k | >>::StreamError, |
311 | 398k | ) -> ParseResult<T, Input::Error> { |
312 | 398k | match self.state { |
313 | | State::Ok => { |
314 | 0 | let err = <Input as StreamOnce>::Error::from_error(self.input.position(), err); |
315 | 0 | if self.committed { |
316 | 0 | CommitErr(err) |
317 | | } else { |
318 | 0 | PeekErr(err.into()) |
319 | | } |
320 | | } |
321 | 2.02k | State::PeekErr(mut e) => { |
322 | 2.02k | let err = <Input as StreamOnce>::Error::from_error(self.input.position(), err); |
323 | 2.02k | e = e.merge(err); |
324 | 2.02k | if self.committed { |
325 | 0 | CommitErr(e) |
326 | | } else { |
327 | 2.02k | PeekErr(e.into()) |
328 | | } |
329 | | } |
330 | 396k | State::CommitErr(mut e) => { |
331 | 396k | e.add(err); |
332 | 396k | CommitErr(e) |
333 | | } |
334 | | } |
335 | 398k | } <combine::parser::repeat::Iter<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, &mut combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>, &mut combine::parser::combinator::AnySendSyncPartialState, combine::parser::PartialMode>>::fail::<alloc::vec::Vec<redis::types::Value>>Line | Count | Source | 304 | 362k | fn fail<T>( | 305 | 362k | self, | 306 | 362k | err: <<Input as StreamOnce>::Error as ParseError< | 307 | 362k | <Input as StreamOnce>::Token, | 308 | 362k | <Input as StreamOnce>::Range, | 309 | 362k | <Input as StreamOnce>::Position, | 310 | 362k | >>::StreamError, | 311 | 362k | ) -> ParseResult<T, Input::Error> { | 312 | 362k | match self.state { | 313 | | State::Ok => { | 314 | 0 | let err = <Input as StreamOnce>::Error::from_error(self.input.position(), err); | 315 | 0 | if self.committed { | 316 | 0 | CommitErr(err) | 317 | | } else { | 318 | 0 | PeekErr(err.into()) | 319 | | } | 320 | | } | 321 | 2.02k | State::PeekErr(mut e) => { | 322 | 2.02k | let err = <Input as StreamOnce>::Error::from_error(self.input.position(), err); | 323 | 2.02k | e = e.merge(err); | 324 | 2.02k | if self.committed { | 325 | 0 | CommitErr(e) | 326 | | } else { | 327 | 2.02k | PeekErr(e.into()) | 328 | | } | 329 | | } | 330 | 360k | State::CommitErr(mut e) => { | 331 | 360k | e.add(err); | 332 | 360k | CommitErr(e) | 333 | | } | 334 | | } | 335 | 362k | } |
<combine::parser::repeat::Iter<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, &mut combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>, &mut combine::parser::combinator::AnySendSyncPartialState, combine::parser::FirstMode>>::fail::<alloc::vec::Vec<redis::types::Value>>Line | Count | Source | 304 | 35.9k | fn fail<T>( | 305 | 35.9k | self, | 306 | 35.9k | err: <<Input as StreamOnce>::Error as ParseError< | 307 | 35.9k | <Input as StreamOnce>::Token, | 308 | 35.9k | <Input as StreamOnce>::Range, | 309 | 35.9k | <Input as StreamOnce>::Position, | 310 | 35.9k | >>::StreamError, | 311 | 35.9k | ) -> ParseResult<T, Input::Error> { | 312 | 35.9k | match self.state { | 313 | | State::Ok => { | 314 | 0 | let err = <Input as StreamOnce>::Error::from_error(self.input.position(), err); | 315 | 0 | if self.committed { | 316 | 0 | CommitErr(err) | 317 | | } else { | 318 | 0 | PeekErr(err.into()) | 319 | | } | 320 | | } | 321 | 0 | State::PeekErr(mut e) => { | 322 | 0 | let err = <Input as StreamOnce>::Error::from_error(self.input.position(), err); | 323 | 0 | e = e.merge(err); | 324 | 0 | if self.committed { | 325 | 0 | CommitErr(e) | 326 | | } else { | 327 | 0 | PeekErr(e.into()) | 328 | | } | 329 | | } | 330 | 35.9k | State::CommitErr(mut e) => { | 331 | 35.9k | e.add(err); | 332 | 35.9k | CommitErr(e) | 333 | | } | 334 | | } | 335 | 35.9k | } |
Unexecuted instantiation: <combine::parser::repeat::Iter<_, _, _, _>>::fail::<_> |
336 | | } |
337 | | |
338 | | impl<'a, Input, P, S, M> Iterator for Iter<'a, Input, P, S, M> |
339 | | where |
340 | | Input: Stream, |
341 | | P: Parser<Input>, |
342 | | S: BorrowMut<P::PartialState>, |
343 | | M: ParseMode, |
344 | | { |
345 | | type Item = P::Output; |
346 | | |
347 | 5.78M | fn next(&mut self) -> Option<P::Output> { |
348 | 5.78M | let before = self.input.checkpoint(); |
349 | 5.78M | match self |
350 | 5.78M | .parser |
351 | 5.78M | .parse_mode(self.mode, self.input, self.partial_state.borrow_mut()) |
352 | | { |
353 | 0 | PeekOk(v) => { |
354 | 0 | self.mode.set_first(); |
355 | 0 | Some(v) |
356 | | } |
357 | 5.38M | CommitOk(v) => { |
358 | 5.38M | self.mode.set_first(); |
359 | 5.38M | self.committed = true; |
360 | 5.38M | Some(v) |
361 | | } |
362 | 2.02k | PeekErr(e) => { |
363 | 2.02k | self.state = match self.input.reset(before) { |
364 | 0 | Err(err) => State::CommitErr(err), |
365 | 2.02k | Ok(_) => State::PeekErr(e.error), |
366 | | }; |
367 | 2.02k | None |
368 | | } |
369 | 396k | CommitErr(e) => { |
370 | 396k | self.state = State::CommitErr(e); |
371 | 396k | None |
372 | | } |
373 | | } |
374 | 5.78M | } <combine::parser::repeat::Iter<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, &mut combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>, &mut combine::parser::combinator::AnySendSyncPartialState, combine::parser::PartialMode> as core::iter::traits::iterator::Iterator>::nextLine | Count | Source | 347 | 5.02M | fn next(&mut self) -> Option<P::Output> { | 348 | 5.02M | let before = self.input.checkpoint(); | 349 | 5.02M | match self | 350 | 5.02M | .parser | 351 | 5.02M | .parse_mode(self.mode, self.input, self.partial_state.borrow_mut()) | 352 | | { | 353 | 0 | PeekOk(v) => { | 354 | 0 | self.mode.set_first(); | 355 | 0 | Some(v) | 356 | | } | 357 | 4.65M | CommitOk(v) => { | 358 | 4.65M | self.mode.set_first(); | 359 | 4.65M | self.committed = true; | 360 | 4.65M | Some(v) | 361 | | } | 362 | 2.02k | PeekErr(e) => { | 363 | 2.02k | self.state = match self.input.reset(before) { | 364 | 0 | Err(err) => State::CommitErr(err), | 365 | 2.02k | Ok(_) => State::PeekErr(e.error), | 366 | | }; | 367 | 2.02k | None | 368 | | } | 369 | 360k | CommitErr(e) => { | 370 | 360k | self.state = State::CommitErr(e); | 371 | 360k | None | 372 | | } | 373 | | } | 374 | 5.02M | } |
<combine::parser::repeat::Iter<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, &mut combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>, &mut combine::parser::combinator::AnySendSyncPartialState, combine::parser::FirstMode> as core::iter::traits::iterator::Iterator>::nextLine | Count | Source | 347 | 765k | fn next(&mut self) -> Option<P::Output> { | 348 | 765k | let before = self.input.checkpoint(); | 349 | 765k | match self | 350 | 765k | .parser | 351 | 765k | .parse_mode(self.mode, self.input, self.partial_state.borrow_mut()) | 352 | | { | 353 | 0 | PeekOk(v) => { | 354 | 0 | self.mode.set_first(); | 355 | 0 | Some(v) | 356 | | } | 357 | 729k | CommitOk(v) => { | 358 | 729k | self.mode.set_first(); | 359 | 729k | self.committed = true; | 360 | 729k | Some(v) | 361 | | } | 362 | 0 | PeekErr(e) => { | 363 | 0 | self.state = match self.input.reset(before) { | 364 | 0 | Err(err) => State::CommitErr(err), | 365 | 0 | Ok(_) => State::PeekErr(e.error), | 366 | | }; | 367 | 0 | None | 368 | | } | 369 | 35.9k | CommitErr(e) => { | 370 | 35.9k | self.state = State::CommitErr(e); | 371 | 35.9k | None | 372 | | } | 373 | | } | 374 | 765k | } |
Unexecuted instantiation: <combine::parser::repeat::Iter<_, _, _, _> as core::iter::traits::iterator::Iterator>::next |
375 | | } |
376 | | |
377 | | #[derive(Copy, Clone)] |
378 | | pub struct Many<F, P>(P, PhantomData<F>); |
379 | | |
380 | | impl<F, Input, P> Parser<Input> for Many<F, P> |
381 | | where |
382 | | Input: Stream, |
383 | | P: Parser<Input>, |
384 | | F: Extend<P::Output> + Default, |
385 | | { |
386 | | type Output = F; |
387 | | type PartialState = (F, P::PartialState); |
388 | | |
389 | | parse_mode!(Input); |
390 | | #[inline] |
391 | 0 | fn parse_mode_impl<M>( |
392 | 0 | &mut self, |
393 | 0 | mode: M, |
394 | 0 | input: &mut Input, |
395 | 0 | state: &mut Self::PartialState, |
396 | 0 | ) -> ParseResult<Self::Output, Input::Error> |
397 | 0 | where |
398 | 0 | M: ParseMode, |
399 | | { |
400 | | // TODO |
401 | 0 | let (ref mut elements, ref mut child_state) = *state; |
402 | | |
403 | 0 | let mut iter = (&mut self.0).partial_iter(mode, input, child_state); |
404 | 0 | elements.extend(iter.by_ref()); |
405 | 0 | iter.into_result_fast(elements) |
406 | 0 | } |
407 | | |
408 | 0 | fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) { |
409 | 0 | self.0.add_error(errors) |
410 | 0 | } |
411 | | |
412 | 0 | fn add_committed_expected_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) { |
413 | 0 | self.add_error(errors); |
414 | 0 | } |
415 | | |
416 | 0 | fn parser_count(&self) -> ErrorOffset { |
417 | 0 | self.0.parser_count() |
418 | 0 | } |
419 | | } |
420 | | |
421 | | /// Parses `p` zero or more times returning a collection with the values from `p`. |
422 | | /// |
423 | | /// If the returned collection cannot be inferred type annotations must be supplied, either by |
424 | | /// annotating the resulting type binding `let collection: Vec<_> = ...` or by specializing when |
425 | | /// calling many, `many::<Vec<_>, _, _>(...)`. |
426 | | /// |
427 | | /// NOTE: If `p` can succeed without consuming any input this may hang forever as `many` will |
428 | | /// repeatedly use `p` to parse the same location in the input every time |
429 | | /// |
430 | | /// ``` |
431 | | /// # extern crate combine; |
432 | | /// # use combine::*; |
433 | | /// # use combine::parser::char::digit; |
434 | | /// # fn main() { |
435 | | /// let result = many(digit()) |
436 | | /// .parse("123A") |
437 | | /// .map(|x| x.0); |
438 | | /// assert_eq!(result, Ok(vec!['1', '2', '3'])); |
439 | | /// # } |
440 | | /// ``` |
441 | 0 | pub fn many<F, Input, P>(p: P) -> Many<F, P> |
442 | 0 | where |
443 | 0 | Input: Stream, |
444 | 0 | P: Parser<Input>, |
445 | 0 | F: Extend<P::Output> + Default, |
446 | | { |
447 | 0 | Many(p, PhantomData) |
448 | 0 | } |
449 | | |
450 | | #[derive(Copy, Clone)] |
451 | | pub struct Many1<F, P>(P, PhantomData<fn() -> F>); |
452 | | impl<F, Input, P> Parser<Input> for Many1<F, P> |
453 | | where |
454 | | Input: Stream, |
455 | | F: Extend<P::Output> + Default, |
456 | | P: Parser<Input>, |
457 | | { |
458 | | type Output = F; |
459 | | type PartialState = (bool, bool, F, P::PartialState); |
460 | | |
461 | | parse_mode!(Input); |
462 | | #[inline] |
463 | 0 | fn parse_mode_impl<M>( |
464 | 0 | &mut self, |
465 | 0 | mut mode: M, |
466 | 0 | input: &mut Input, |
467 | 0 | state: &mut Self::PartialState, |
468 | 0 | ) -> ParseResult<F, Input::Error> |
469 | 0 | where |
470 | 0 | M: ParseMode, |
471 | | { |
472 | 0 | let (ref mut parsed_one, ref mut committed_state, ref mut elements, ref mut child_state) = |
473 | 0 | *state; |
474 | | |
475 | 0 | if mode.is_first() || !*parsed_one { |
476 | 0 | debug_assert!(!*parsed_one); |
477 | | |
478 | 0 | let (first, committed) = ctry!(self.0.parse_mode(mode, input, child_state)); |
479 | 0 | elements.extend(Some(first)); |
480 | | // TODO Should PeekOk be an error? |
481 | 0 | *committed_state = !committed.is_peek(); |
482 | 0 | *parsed_one = true; |
483 | 0 | mode.set_first(); |
484 | 0 | } |
485 | | |
486 | 0 | let mut iter = Iter { |
487 | 0 | parser: &mut self.0, |
488 | 0 | committed: *committed_state, |
489 | 0 | input, |
490 | 0 | state: State::Ok, |
491 | 0 | partial_state: child_state, |
492 | 0 | mode, |
493 | 0 | }; |
494 | 0 | elements.extend(iter.by_ref()); |
495 | | |
496 | 0 | iter.into_result_fast(elements).map(|x| { |
497 | 0 | *parsed_one = false; |
498 | 0 | x |
499 | 0 | }) |
500 | 0 | } |
501 | | |
502 | 0 | fn add_committed_expected_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) { |
503 | 0 | self.add_error(errors); |
504 | 0 | } |
505 | | |
506 | | forward_parser!(Input, add_error parser_count, 0); |
507 | | } |
508 | | |
509 | | /// Parses `p` one or more times returning a collection with the values from `p`. |
510 | | /// |
511 | | /// If the returned collection cannot be inferred type annotations must be supplied, either by |
512 | | /// annotating the resulting type binding `let collection: Vec<_> = ...` or by specializing when |
513 | | /// calling many1 `many1::<Vec<_>, _>(...)`. |
514 | | /// |
515 | | /// NOTE: If `p` can succeed without consuming any input this may hang forever as `many1` will |
516 | | /// repeatedly use `p` to parse the same location in the input every time |
517 | | /// |
518 | | /// |
519 | | /// ``` |
520 | | /// # extern crate combine; |
521 | | /// # use combine::*; |
522 | | /// # use combine::parser::char::digit; |
523 | | /// # fn main() { |
524 | | /// let result = many1::<Vec<_>, _, _>(digit()) |
525 | | /// .parse("A123"); |
526 | | /// assert!(result.is_err()); |
527 | | /// # } |
528 | | /// ``` |
529 | 0 | pub fn many1<F, Input, P>(p: P) -> Many1<F, P> |
530 | 0 | where |
531 | 0 | Input: Stream, |
532 | 0 | F: Extend<P::Output> + Default, |
533 | 0 | P: Parser<Input>, |
534 | | { |
535 | 0 | Many1(p, PhantomData) |
536 | 0 | } |
537 | | |
538 | | #[derive(Clone)] |
539 | | #[doc(hidden)] |
540 | | // FIXME Should not be public |
541 | | pub struct Sink; |
542 | | |
543 | | impl Default for Sink { |
544 | 0 | fn default() -> Self { |
545 | 0 | Sink |
546 | 0 | } |
547 | | } |
548 | | |
549 | | impl<A> Extend<A> for Sink { |
550 | 0 | fn extend<T>(&mut self, iter: T) |
551 | 0 | where |
552 | 0 | T: IntoIterator<Item = A>, |
553 | | { |
554 | 0 | for _ in iter {} |
555 | 0 | } |
556 | | } |
557 | | |
558 | | parser! { |
559 | | pub struct SkipMany; |
560 | | type PartialState = <Ignore<Many<Sink, Ignore<P>>> as Parser<Input>>::PartialState; |
561 | | /// Parses `p` zero or more times ignoring the result. |
562 | | /// |
563 | | /// NOTE: If `p` can succeed without consuming any input this may hang forever as `skip_many` will |
564 | | /// repeatedly use `p` to parse the same location in the input every time |
565 | | /// |
566 | | /// ``` |
567 | | /// # extern crate combine; |
568 | | /// # use combine::*; |
569 | | /// # use combine::parser::char::digit; |
570 | | /// # fn main() { |
571 | | /// let result = skip_many(digit()) |
572 | | /// .parse("A"); |
573 | | /// assert_eq!(result, Ok(((), "A"))); |
574 | | /// # } |
575 | | /// ``` |
576 | | pub fn skip_many[Input, P](p: P)(Input) -> () |
577 | | where [ |
578 | | P: Parser<Input>, |
579 | | ] |
580 | | { |
581 | | ignore(many::<Sink, _, _>(ignore(p))) |
582 | | } |
583 | | } |
584 | | |
585 | | parser! { |
586 | | pub struct SkipMany1; |
587 | | type PartialState = <Ignore<Many1<Sink, Ignore<P>>> as Parser<Input>>::PartialState; |
588 | | /// Parses `p` one or more times ignoring the result. |
589 | | /// |
590 | | /// NOTE: If `p` can succeed without consuming any input this may hang forever as `skip_many1` will |
591 | | /// repeatedly use `p` to parse the same location in the input every time |
592 | | /// |
593 | | /// ``` |
594 | | /// # extern crate combine; |
595 | | /// # use combine::*; |
596 | | /// # use combine::parser::char::digit; |
597 | | /// # fn main() { |
598 | | /// let result = skip_many1(digit()) |
599 | | /// .parse("123A"); |
600 | | /// assert_eq!(result, Ok(((), "A"))); |
601 | | /// # } |
602 | | /// ``` |
603 | | pub fn skip_many1[Input, P](p: P)(Input) -> () |
604 | | where [ |
605 | | P: Parser<Input>, |
606 | | ] |
607 | | { |
608 | | ignore(many1::<Sink, _, _>(ignore(p))) |
609 | | } |
610 | | } |
611 | | |
612 | | #[derive(Copy, Clone)] |
613 | | pub struct SepBy<F, P, S> { |
614 | | parser: P, |
615 | | separator: S, |
616 | | _marker: PhantomData<fn() -> F>, |
617 | | } |
618 | | impl<F, Input, P, S> Parser<Input> for SepBy<F, P, S> |
619 | | where |
620 | | Input: Stream, |
621 | | F: Extend<P::Output> + Default, |
622 | | P: Parser<Input>, |
623 | | S: Parser<Input>, |
624 | | { |
625 | | type Output = F; |
626 | | type PartialState = <Or< |
627 | | SepBy1<F, P, S>, |
628 | | FnParser<Input, fn(&mut Input) -> StdParseResult<F, Input>>, |
629 | | > as Parser<Input>>::PartialState; |
630 | | |
631 | | parse_mode!(Input); |
632 | | #[inline] |
633 | 0 | fn parse_mode_impl<M>( |
634 | 0 | &mut self, |
635 | 0 | mode: M, |
636 | 0 | input: &mut Input, |
637 | 0 | state: &mut Self::PartialState, |
638 | 0 | ) -> ParseResult<F, Input::Error> |
639 | 0 | where |
640 | 0 | M: ParseMode, |
641 | | { |
642 | 0 | sep_by1(&mut self.parser, &mut self.separator) |
643 | 0 | .or(parser(|_| Ok((F::default(), Commit::Peek(()))))) |
644 | 0 | .parse_mode(mode, input, state) |
645 | 0 | } |
646 | | |
647 | 0 | fn add_committed_expected_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) { |
648 | 0 | self.separator.add_error(errors) |
649 | 0 | } |
650 | | |
651 | | forward_parser!(Input, add_error parser_count, parser); |
652 | | } |
653 | | |
654 | | /// Parses `parser` zero or more time separated by `separator`, returning a collection with the |
655 | | /// values from `p`. |
656 | | /// |
657 | | /// If the returned collection cannot be inferred type annotations must be supplied, either by |
658 | | /// annotating the resulting type binding `let collection: Vec<_> = ...` or by specializing when |
659 | | /// calling `sep_by`, `sep_by::<Vec<_>, _, _>(...)`. |
660 | | /// |
661 | | /// ``` |
662 | | /// # extern crate combine; |
663 | | /// # use combine::*; |
664 | | /// # use combine::parser::char::digit; |
665 | | /// # fn main() { |
666 | | /// let mut parser = sep_by(digit(), token(',')); |
667 | | /// let result_ok = parser.parse("1,2,3"); |
668 | | /// assert_eq!(result_ok, Ok((vec!['1', '2', '3'], ""))); |
669 | | /// let result_ok2 = parser.parse(""); |
670 | | /// assert_eq!(result_ok2, Ok((vec![], ""))); |
671 | | /// # } |
672 | | /// ``` |
673 | 0 | pub fn sep_by<F, Input, P, S>(parser: P, separator: S) -> SepBy<F, P, S> |
674 | 0 | where |
675 | 0 | Input: Stream, |
676 | 0 | F: Extend<P::Output> + Default, |
677 | 0 | P: Parser<Input>, |
678 | 0 | S: Parser<Input>, |
679 | | { |
680 | 0 | SepBy { |
681 | 0 | parser, |
682 | 0 | separator, |
683 | 0 | _marker: PhantomData, |
684 | 0 | } |
685 | 0 | } |
686 | | |
687 | | #[derive(Copy, Clone)] |
688 | | pub struct SepBy1<F, P, S> { |
689 | | parser: P, |
690 | | separator: S, |
691 | | _marker: PhantomData<fn() -> F>, |
692 | | } |
693 | | impl<F, Input, P, S> Parser<Input> for SepBy1<F, P, S> |
694 | | where |
695 | | Input: Stream, |
696 | | F: Extend<P::Output> + Default, |
697 | | P: Parser<Input>, |
698 | | S: Parser<Input>, |
699 | | { |
700 | | type Output = F; |
701 | | type PartialState = ( |
702 | | Option<Commit<()>>, |
703 | | F, |
704 | | <With<S, P> as Parser<Input>>::PartialState, |
705 | | ); |
706 | | |
707 | | parse_mode!(Input); |
708 | | #[inline] |
709 | 0 | fn parse_mode_impl<M>( |
710 | 0 | &mut self, |
711 | 0 | mode: M, |
712 | 0 | input: &mut Input, |
713 | 0 | state: &mut Self::PartialState, |
714 | 0 | ) -> ParseResult<Self::Output, Input::Error> |
715 | 0 | where |
716 | 0 | M: ParseMode, |
717 | | { |
718 | 0 | let (ref mut parsed_one, ref mut elements, ref mut child_state) = *state; |
719 | | |
720 | 0 | let rest = match *parsed_one { |
721 | 0 | Some(rest) => rest, |
722 | | None => { |
723 | 0 | let (first, rest) = |
724 | 0 | ctry!(self |
725 | 0 | .parser |
726 | 0 | .parse_mode(mode, input, &mut child_state.B.state)); |
727 | 0 | elements.extend(Some(first)); |
728 | 0 | rest |
729 | | } |
730 | | }; |
731 | | |
732 | 0 | rest.combine_commit(move |_| { |
733 | 0 | let rest = (&mut self.separator).with(&mut self.parser); |
734 | 0 | let mut iter = Iter::new(rest, mode, input, child_state); |
735 | | |
736 | 0 | elements.extend(iter.by_ref()); |
737 | | |
738 | 0 | iter.into_result_fast(elements).map(|x| { |
739 | 0 | *parsed_one = None; |
740 | 0 | x |
741 | 0 | }) |
742 | 0 | }) |
743 | 0 | } |
744 | | |
745 | 0 | fn add_committed_expected_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) { |
746 | 0 | self.separator.add_error(errors) |
747 | 0 | } |
748 | | |
749 | | forward_parser!(Input, add_error parser_count, parser); |
750 | | } |
751 | | |
752 | | /// Parses `parser` one or more time separated by `separator`, returning a collection with the |
753 | | /// values from `p`. |
754 | | /// |
755 | | /// If the returned collection cannot be inferred type annotations must be supplied, either by |
756 | | /// annotating the resulting type binding `let collection: Vec<_> = ...` or by specializing when |
757 | | /// calling `sep_by`, `sep_by1::<Vec<_>, _, _>(...)`. |
758 | | /// |
759 | | /// ``` |
760 | | /// # extern crate combine; |
761 | | /// # use combine::*; |
762 | | /// # use combine::parser::char::digit; |
763 | | /// # use combine::stream::easy; |
764 | | /// # use combine::stream::position::{self, SourcePosition}; |
765 | | /// # fn main() { |
766 | | /// let mut parser = sep_by1(digit(), token(',')); |
767 | | /// let result_ok = parser.easy_parse(position::Stream::new("1,2,3")) |
768 | | /// .map(|(vec, state)| (vec, state.input)); |
769 | | /// assert_eq!(result_ok, Ok((vec!['1', '2', '3'], ""))); |
770 | | /// let result_err = parser.easy_parse(position::Stream::new("")); |
771 | | /// assert_eq!(result_err, Err(easy::Errors { |
772 | | /// position: SourcePosition::default(), |
773 | | /// errors: vec![ |
774 | | /// easy::Error::end_of_input(), |
775 | | /// easy::Error::Expected("digit".into()) |
776 | | /// ] |
777 | | /// })); |
778 | | /// # } |
779 | | /// ``` |
780 | 0 | pub fn sep_by1<F, Input, P, S>(parser: P, separator: S) -> SepBy1<F, P, S> |
781 | 0 | where |
782 | 0 | Input: Stream, |
783 | 0 | F: Extend<P::Output> + Default, |
784 | 0 | P: Parser<Input>, |
785 | 0 | S: Parser<Input>, |
786 | | { |
787 | 0 | SepBy1 { |
788 | 0 | parser, |
789 | 0 | separator, |
790 | 0 | _marker: PhantomData, |
791 | 0 | } |
792 | 0 | } |
793 | | |
794 | | #[derive(Copy, Clone)] |
795 | | pub struct SepEndBy<F, P, S> { |
796 | | parser: P, |
797 | | separator: S, |
798 | | _marker: PhantomData<fn() -> F>, |
799 | | } |
800 | | |
801 | | impl<F, Input, P, S> Parser<Input> for SepEndBy<F, P, S> |
802 | | where |
803 | | Input: Stream, |
804 | | F: Extend<P::Output> + Default, |
805 | | P: Parser<Input>, |
806 | | S: Parser<Input>, |
807 | | { |
808 | | type Output = F; |
809 | | type PartialState = <Or< |
810 | | SepEndBy1<F, P, S>, |
811 | | FnParser<Input, fn(&mut Input) -> StdParseResult<F, Input>>, |
812 | | > as Parser<Input>>::PartialState; |
813 | | |
814 | | parse_mode!(Input); |
815 | | #[inline] |
816 | 0 | fn parse_mode_impl<M>( |
817 | 0 | &mut self, |
818 | 0 | mode: M, |
819 | 0 | input: &mut Input, |
820 | 0 | state: &mut Self::PartialState, |
821 | 0 | ) -> ParseResult<Self::Output, Input::Error> |
822 | 0 | where |
823 | 0 | M: ParseMode, |
824 | | { |
825 | 0 | sep_end_by1(&mut self.parser, &mut self.separator) |
826 | 0 | .or(parser(|_| Ok((F::default(), Commit::Peek(()))))) |
827 | 0 | .parse_mode(mode, input, state) |
828 | 0 | } |
829 | | |
830 | 0 | fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) { |
831 | 0 | self.parser.add_error(errors) |
832 | 0 | } |
833 | | } |
834 | | |
835 | | /// Parses `parser` zero or more times separated and ended by `separator`, returning a collection |
836 | | /// with the values from `p`. |
837 | | /// |
838 | | /// If the returned collection cannot be inferred type annotations must be supplied, either by |
839 | | /// annotating the resulting type binding `let collection: Vec<_> = ...` or by specializing when |
840 | | /// calling `sep_by`, `sep_by::<Vec<_>, _, _>(...)` |
841 | | /// |
842 | | /// ``` |
843 | | /// # extern crate combine; |
844 | | /// # use combine::*; |
845 | | /// # use combine::parser::char::digit; |
846 | | /// # fn main() { |
847 | | /// let mut parser = sep_end_by(digit(), token(';')); |
848 | | /// let result_ok = parser.parse("1;2;3;"); |
849 | | /// assert_eq!(result_ok, Ok((vec!['1', '2', '3'], ""))); |
850 | | /// let result_ok2 = parser.parse("1;2;3"); |
851 | | /// assert_eq!(result_ok2, Ok((vec!['1', '2', '3'], ""))); |
852 | | /// # } |
853 | | /// ``` |
854 | 0 | pub fn sep_end_by<F, Input, P, S>(parser: P, separator: S) -> SepEndBy<F, P, S> |
855 | 0 | where |
856 | 0 | Input: Stream, |
857 | 0 | F: Extend<P::Output> + Default, |
858 | 0 | P: Parser<Input>, |
859 | 0 | S: Parser<Input>, |
860 | | { |
861 | 0 | SepEndBy { |
862 | 0 | parser, |
863 | 0 | separator, |
864 | 0 | _marker: PhantomData, |
865 | 0 | } |
866 | 0 | } |
867 | | |
868 | | #[derive(Copy, Clone)] |
869 | | pub struct SepEndBy1<F, P, S> { |
870 | | parser: P, |
871 | | separator: S, |
872 | | _marker: PhantomData<fn() -> F>, |
873 | | } |
874 | | |
875 | | impl<F, Input, P, S> Parser<Input> for SepEndBy1<F, P, S> |
876 | | where |
877 | | Input: Stream, |
878 | | F: Extend<P::Output> + Default, |
879 | | P: Parser<Input>, |
880 | | S: Parser<Input>, |
881 | | { |
882 | | type Output = F; |
883 | | type PartialState = ( |
884 | | Option<Commit<()>>, |
885 | | F, |
886 | | <With<S, Optional<P>> as Parser<Input>>::PartialState, |
887 | | ); |
888 | | |
889 | | parse_mode!(Input); |
890 | | #[inline] |
891 | 0 | fn parse_mode_impl<M>( |
892 | 0 | &mut self, |
893 | 0 | mode: M, |
894 | 0 | input: &mut Input, |
895 | 0 | state: &mut Self::PartialState, |
896 | 0 | ) -> ParseResult<Self::Output, Input::Error> |
897 | 0 | where |
898 | 0 | M: ParseMode, |
899 | | { |
900 | 0 | let (ref mut parsed_one, ref mut elements, ref mut child_state) = *state; |
901 | | |
902 | 0 | let rest = match *parsed_one { |
903 | 0 | Some(rest) => rest, |
904 | | None => { |
905 | 0 | let (first, rest) = |
906 | 0 | ctry!(self |
907 | 0 | .parser |
908 | 0 | .parse_mode(mode, input, &mut child_state.B.state)); |
909 | 0 | *parsed_one = Some(rest); |
910 | 0 | elements.extend(Some(first)); |
911 | 0 | rest |
912 | | } |
913 | | }; |
914 | | |
915 | 0 | rest.combine_commit(|_| { |
916 | 0 | let rest = (&mut self.separator).with(optional(&mut self.parser)); |
917 | 0 | let mut iter = Iter::new(rest, mode, input, child_state); |
918 | | |
919 | | // Parse elements until `self.parser` returns `None` |
920 | 0 | elements.extend(iter.by_ref().scan((), |_, x| x)); |
921 | | |
922 | 0 | if iter.committed { |
923 | 0 | *parsed_one = Some(Commit::Commit(())); |
924 | 0 | } |
925 | | |
926 | 0 | iter.into_result_fast(elements).map(|x| { |
927 | 0 | *parsed_one = None; |
928 | 0 | x |
929 | 0 | }) |
930 | 0 | }) |
931 | 0 | } |
932 | | |
933 | 0 | fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) { |
934 | 0 | self.parser.add_error(errors) |
935 | 0 | } |
936 | | } |
937 | | |
938 | | /// Parses `parser` one or more times separated and ended by `separator`, returning a collection |
939 | | /// with the values from `p`. |
940 | | /// |
941 | | /// If the returned collection cannot be inferred type annotations must be |
942 | | /// supplied, either by annotating the resulting type binding `let collection: Vec<_> = ...` or by |
943 | | /// specializing when calling `sep_by`, `sep_by1::<Vec<_>, _, _>(...)`. |
944 | | /// |
945 | | /// ``` |
946 | | /// # extern crate combine; |
947 | | /// # use combine::*; |
948 | | /// # use combine::parser::char::digit; |
949 | | /// # use combine::stream::easy; |
950 | | /// # use combine::stream::position::{self, SourcePosition}; |
951 | | /// # fn main() { |
952 | | /// let mut parser = sep_end_by1(digit(), token(';')); |
953 | | /// let result_ok = parser.easy_parse(position::Stream::new("1;2;3;")) |
954 | | /// .map(|(vec, state)| (vec, state.input)); |
955 | | /// assert_eq!(result_ok, Ok((vec!['1', '2', '3'], ""))); |
956 | | /// let result_err = parser.easy_parse(position::Stream::new("")); |
957 | | /// assert_eq!(result_err, Err(easy::Errors { |
958 | | /// position: SourcePosition::default(), |
959 | | /// errors: vec![ |
960 | | /// easy::Error::end_of_input(), |
961 | | /// easy::Error::Expected("digit".into()) |
962 | | /// ] |
963 | | /// })); |
964 | | /// # } |
965 | | /// ``` |
966 | 0 | pub fn sep_end_by1<F, Input, P, S>(parser: P, separator: S) -> SepEndBy1<F, P, S> |
967 | 0 | where |
968 | 0 | Input: Stream, |
969 | 0 | F: Extend<P::Output> + Default, |
970 | 0 | P: Parser<Input>, |
971 | 0 | S: Parser<Input>, |
972 | | { |
973 | 0 | SepEndBy1 { |
974 | 0 | parser, |
975 | 0 | separator, |
976 | 0 | _marker: PhantomData, |
977 | 0 | } |
978 | 0 | } |
979 | | |
980 | | #[derive(Copy, Clone)] |
981 | | pub struct Chainl1<P, Op>(P, Op); |
982 | | impl<Input, P, Op> Parser<Input> for Chainl1<P, Op> |
983 | | where |
984 | | Input: Stream, |
985 | | P: Parser<Input>, |
986 | | Op: Parser<Input>, |
987 | | Op::Output: FnOnce(P::Output, P::Output) -> P::Output, |
988 | | { |
989 | | type Output = P::Output; |
990 | | type PartialState = ( |
991 | | Option<(P::Output, Commit<()>)>, |
992 | | <(Op, P) as Parser<Input>>::PartialState, |
993 | | ); |
994 | | |
995 | | parse_mode!(Input); |
996 | | #[inline] |
997 | 0 | fn parse_mode_impl<M>( |
998 | 0 | &mut self, |
999 | 0 | mut mode: M, |
1000 | 0 | input: &mut Input, |
1001 | 0 | state: &mut Self::PartialState, |
1002 | 0 | ) -> ParseResult<Self::Output, Input::Error> |
1003 | 0 | where |
1004 | 0 | M: ParseMode, |
1005 | | { |
1006 | 0 | let (ref mut l_state, ref mut child_state) = *state; |
1007 | | |
1008 | 0 | let (mut l, mut committed) = match l_state.take() { |
1009 | 0 | Some(x) => x, |
1010 | | None => { |
1011 | 0 | let x = ctry!(self.0.parse_partial(input, &mut child_state.B.state)); |
1012 | 0 | mode.set_first(); |
1013 | 0 | x |
1014 | | } |
1015 | | }; |
1016 | | |
1017 | | loop { |
1018 | 0 | let before = input.checkpoint(); |
1019 | 0 | match (&mut self.1, &mut self.0) |
1020 | 0 | .parse_mode(mode, input, child_state) |
1021 | 0 | .into() |
1022 | | { |
1023 | 0 | Ok(((op, r), rest)) => { |
1024 | 0 | l = op(l, r); |
1025 | 0 | committed = committed.merge(rest); |
1026 | 0 | mode.set_first(); |
1027 | 0 | } |
1028 | 0 | Err(Commit::Commit(err)) => { |
1029 | 0 | *l_state = Some((l, committed)); |
1030 | 0 | return CommitErr(err.error); |
1031 | | } |
1032 | | Err(Commit::Peek(_)) => { |
1033 | 0 | ctry!(input.reset(before).committed()); |
1034 | 0 | break; |
1035 | | } |
1036 | | } |
1037 | | } |
1038 | 0 | Ok((l, committed)).into() |
1039 | 0 | } |
1040 | | |
1041 | 0 | fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) { |
1042 | 0 | self.0.add_error(errors) |
1043 | 0 | } |
1044 | | } |
1045 | | |
1046 | | /// Parses `p` 1 or more times separated by `op`. The value returned is the one produced by the |
1047 | | /// left associative application of the function returned by the parser `op`. |
1048 | | /// |
1049 | | /// ``` |
1050 | | /// # extern crate combine; |
1051 | | /// # use combine::*; |
1052 | | /// # use combine::parser::char::digit; |
1053 | | /// # fn main() { |
1054 | | /// let number = digit().map(|c: char| c.to_digit(10).unwrap()); |
1055 | | /// let sub = token('-').map(|_| |l: u32, r: u32| l - r); |
1056 | | /// let mut parser = chainl1(number, sub); |
1057 | | /// assert_eq!(parser.parse("9-3-5"), Ok((1, ""))); |
1058 | | /// # } |
1059 | | /// ``` |
1060 | 0 | pub fn chainl1<Input, P, Op>(parser: P, op: Op) -> Chainl1<P, Op> |
1061 | 0 | where |
1062 | 0 | Input: Stream, |
1063 | 0 | P: Parser<Input>, |
1064 | 0 | Op: Parser<Input>, |
1065 | 0 | Op::Output: FnOnce(P::Output, P::Output) -> P::Output, |
1066 | | { |
1067 | 0 | Chainl1(parser, op) |
1068 | 0 | } |
1069 | | |
1070 | | #[derive(Copy, Clone)] |
1071 | | pub struct Chainr1<P, Op>(P, Op); |
1072 | | impl<Input, P, Op> Parser<Input> for Chainr1<P, Op> |
1073 | | where |
1074 | | Input: Stream, |
1075 | | P: Parser<Input>, |
1076 | | Op: Parser<Input>, |
1077 | | Op::Output: FnOnce(P::Output, P::Output) -> P::Output, |
1078 | | { |
1079 | | type Output = P::Output; |
1080 | | type PartialState = (); |
1081 | | #[inline] |
1082 | 0 | fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<P::Output, Input::Error> { |
1083 | | // FIXME FastResult |
1084 | 0 | let (mut l, mut committed) = ctry!(self.0.parse_lazy(input)); |
1085 | | loop { |
1086 | 0 | let before = input.checkpoint(); |
1087 | 0 | let op = match self.1.parse_lazy(input).into() { |
1088 | 0 | Ok((x, rest)) => { |
1089 | 0 | committed = committed.merge(rest); |
1090 | 0 | x |
1091 | | } |
1092 | 0 | Err(Commit::Commit(err)) => return CommitErr(err.error), |
1093 | | Err(Commit::Peek(_)) => { |
1094 | 0 | ctry!(input.reset(before).committed()); |
1095 | 0 | break; |
1096 | | } |
1097 | | }; |
1098 | 0 | let before = input.checkpoint(); |
1099 | 0 | match self.parse_lazy(input).into() { |
1100 | 0 | Ok((r, rest)) => { |
1101 | 0 | l = op(l, r); |
1102 | 0 | committed = committed.merge(rest); |
1103 | 0 | } |
1104 | 0 | Err(Commit::Commit(err)) => return CommitErr(err.error), |
1105 | | Err(Commit::Peek(_)) => { |
1106 | 0 | ctry!(input.reset(before).committed()); |
1107 | 0 | break; |
1108 | | } |
1109 | | } |
1110 | | } |
1111 | 0 | Ok((l, committed)).into() |
1112 | 0 | } |
1113 | 0 | fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) { |
1114 | 0 | self.0.add_error(errors) |
1115 | 0 | } |
1116 | | } |
1117 | | |
1118 | | /// Parses `p` one or more times separated by `op`. The value returned is the one produced by the |
1119 | | /// right associative application of the function returned by `op`. |
1120 | | /// |
1121 | | /// ``` |
1122 | | /// # extern crate combine; |
1123 | | /// # use combine::*; |
1124 | | /// # use combine::parser::char::digit; |
1125 | | /// # fn main() { |
1126 | | /// let number = digit().map(|c: char| c.to_digit(10).unwrap()); |
1127 | | /// let pow = token('^').map(|_| |l: u32, r: u32| l.pow(r)); |
1128 | | /// let mut parser = chainr1(number, pow); |
1129 | | /// assert_eq!(parser.parse("2^3^2"), Ok((512, ""))); |
1130 | | /// } |
1131 | | /// ``` |
1132 | 0 | pub fn chainr1<Input, P, Op>(parser: P, op: Op) -> Chainr1<P, Op> |
1133 | 0 | where |
1134 | 0 | Input: Stream, |
1135 | 0 | P: Parser<Input>, |
1136 | 0 | Op: Parser<Input>, |
1137 | 0 | Op::Output: FnOnce(P::Output, P::Output) -> P::Output, |
1138 | | { |
1139 | 0 | Chainr1(parser, op) |
1140 | 0 | } |
1141 | | |
1142 | | #[derive(Copy, Clone)] |
1143 | | pub struct TakeUntil<F, P> { |
1144 | | end: P, |
1145 | | _marker: PhantomData<fn() -> F>, |
1146 | | } |
1147 | | impl<F, Input, P> Parser<Input> for TakeUntil<F, P> |
1148 | | where |
1149 | | Input: Stream, |
1150 | | F: Extend<<Input as StreamOnce>::Token> + Default, |
1151 | | P: Parser<Input>, |
1152 | | { |
1153 | | type Output = F; |
1154 | | type PartialState = (F, P::PartialState); |
1155 | | |
1156 | | parse_mode!(Input); |
1157 | | #[inline] |
1158 | 0 | fn parse_mode_impl<M>( |
1159 | 0 | &mut self, |
1160 | 0 | mode: M, |
1161 | 0 | input: &mut Input, |
1162 | 0 | state: &mut Self::PartialState, |
1163 | 0 | ) -> ParseResult<Self::Output, Input::Error> |
1164 | 0 | where |
1165 | 0 | M: ParseMode, |
1166 | | { |
1167 | 0 | let (ref mut output, ref mut end_state) = *state; |
1168 | | |
1169 | 0 | let mut committed = Commit::Peek(()); |
1170 | | loop { |
1171 | 0 | let before = input.checkpoint(); |
1172 | 0 | match self.end.parse_mode(mode, input, end_state).into() { |
1173 | 0 | Ok((_, rest)) => { |
1174 | 0 | ctry!(input.reset(before).committed()); |
1175 | 0 | return match committed.merge(rest) { |
1176 | 0 | Commit::Commit(()) => CommitOk(mem::take(output)), |
1177 | 0 | Commit::Peek(()) => PeekOk(mem::take(output)), |
1178 | | }; |
1179 | | } |
1180 | | Err(Commit::Peek(_)) => { |
1181 | 0 | ctry!(input.reset(before).committed()); |
1182 | 0 | output.extend(Some(ctry!(uncons(input)).0)); |
1183 | 0 | committed = Commit::Commit(()); |
1184 | | } |
1185 | 0 | Err(Commit::Commit(e)) => { |
1186 | 0 | ctry!(input.reset(before).committed()); |
1187 | 0 | return CommitErr(e.error); |
1188 | | } |
1189 | | }; |
1190 | | } |
1191 | 0 | } |
1192 | | } |
1193 | | |
1194 | | /// Takes input until `end` is encountered or `end` indicates that it has committed input before |
1195 | | /// failing (`attempt` can be used to make it look like it has not committed any input) |
1196 | | /// |
1197 | | /// ``` |
1198 | | /// # extern crate combine; |
1199 | | /// # use combine::*; |
1200 | | /// # use combine::parser::char; |
1201 | | /// # use combine::parser::byte; |
1202 | | /// # use combine::parser::combinator::attempt; |
1203 | | /// # use combine::parser::repeat::take_until; |
1204 | | /// # fn main() { |
1205 | | /// let mut char_parser = take_until(char::digit()); |
1206 | | /// assert_eq!(char_parser.parse("abc123"), Ok(("abc".to_string(), "123"))); |
1207 | | /// |
1208 | | /// let mut byte_parser = take_until(byte::bytes(&b"TAG"[..])); |
1209 | | /// assert_eq!(byte_parser.parse(&b"123TAG"[..]), Ok((b"123".to_vec(), &b"TAG"[..]))); |
1210 | | /// assert!(byte_parser.parse(&b"123TATAG"[..]).is_err()); |
1211 | | /// |
1212 | | /// // `attempt` must be used if the `end` should be consume input before failing |
1213 | | /// let mut byte_parser = take_until(attempt(byte::bytes(&b"TAG"[..]))); |
1214 | | /// assert_eq!(byte_parser.parse(&b"123TATAG"[..]), Ok((b"123TA".to_vec(), &b"TAG"[..]))); |
1215 | | /// # } |
1216 | | /// ``` |
1217 | 0 | pub fn take_until<F, Input, P>(end: P) -> TakeUntil<F, P> |
1218 | 0 | where |
1219 | 0 | Input: Stream, |
1220 | 0 | F: Extend<<Input as StreamOnce>::Token> + Default, |
1221 | 0 | P: Parser<Input>, |
1222 | | { |
1223 | 0 | TakeUntil { |
1224 | 0 | end, |
1225 | 0 | _marker: PhantomData, |
1226 | 0 | } |
1227 | 0 | } |
1228 | | |
1229 | | parser! { |
1230 | | pub struct SkipUntil; |
1231 | | type PartialState = <With<TakeUntil<Sink, P>, Value<Input, ()>> as Parser<Input>>::PartialState; |
1232 | | /// Skips input until `end` is encountered or `end` indicates that it has committed input before |
1233 | | /// failing (`attempt` can be used to make it look like it has not committed any input) |
1234 | | /// |
1235 | | /// ``` |
1236 | | /// # extern crate combine; |
1237 | | /// # use combine::*; |
1238 | | /// # use combine::parser::char; |
1239 | | /// # use combine::parser::byte; |
1240 | | /// # use combine::parser::combinator::attempt; |
1241 | | /// # use combine::parser::repeat::skip_until; |
1242 | | /// # fn main() { |
1243 | | /// let mut char_parser = skip_until(char::digit()); |
1244 | | /// assert_eq!(char_parser.parse("abc123"), Ok(((), "123"))); |
1245 | | /// |
1246 | | /// let mut byte_parser = skip_until(byte::bytes(&b"TAG"[..])); |
1247 | | /// assert_eq!(byte_parser.parse(&b"123TAG"[..]), Ok(((), &b"TAG"[..]))); |
1248 | | /// assert!(byte_parser.parse(&b"123TATAG"[..]).is_err()); |
1249 | | /// |
1250 | | /// // `attempt` must be used if the `end` should consume input before failing |
1251 | | /// let mut byte_parser = skip_until(attempt(byte::bytes(&b"TAG"[..]))); |
1252 | | /// assert_eq!(byte_parser.parse(&b"123TATAG"[..]), Ok(((), &b"TAG"[..]))); |
1253 | | /// # } |
1254 | | /// ``` |
1255 | | pub fn skip_until[Input, P](end: P)(Input) -> () |
1256 | | where [ |
1257 | | P: Parser<Input>, |
1258 | | ] |
1259 | | { |
1260 | | take_until::<Sink, _, _>(end).with(value(())) |
1261 | | } |
1262 | | } |
1263 | | |
1264 | | #[derive(Copy, Clone)] |
1265 | | pub struct RepeatUntil<F, P, E> { |
1266 | | parser: P, |
1267 | | end: E, |
1268 | | _marker: PhantomData<fn() -> F>, |
1269 | | } |
1270 | | impl<F, Input, P, E> Parser<Input> for RepeatUntil<F, P, E> |
1271 | | where |
1272 | | Input: Stream, |
1273 | | F: Extend<P::Output> + Default, |
1274 | | P: Parser<Input>, |
1275 | | E: Parser<Input>, |
1276 | | { |
1277 | | type Output = F; |
1278 | | type PartialState = (F, bool, P::PartialState, E::PartialState); |
1279 | | |
1280 | | parse_mode!(Input); |
1281 | | #[inline] |
1282 | 0 | fn parse_mode_impl<M>( |
1283 | 0 | &mut self, |
1284 | 0 | mut mode: M, |
1285 | 0 | input: &mut Input, |
1286 | 0 | state: &mut Self::PartialState, |
1287 | 0 | ) -> ParseResult<Self::Output, Input::Error> |
1288 | 0 | where |
1289 | 0 | M: ParseMode, |
1290 | | { |
1291 | 0 | let (output, is_parse, parse_state, end_state) = state; |
1292 | | |
1293 | 0 | let mut committed = Commit::Peek(()); |
1294 | | loop { |
1295 | 0 | if *is_parse { |
1296 | 0 | let (token, c) = ctry!(self.parser.parse_mode(mode, input, parse_state)); |
1297 | 0 | output.extend(Some(token)); |
1298 | 0 | committed = committed.merge(c); |
1299 | 0 | *is_parse = false; |
1300 | | } else { |
1301 | 0 | let before = input.checkpoint(); |
1302 | 0 | match self.end.parse_mode(mode, input, end_state).into() { |
1303 | 0 | Ok((_, rest)) => { |
1304 | 0 | ctry!(input.reset(before).committed()); |
1305 | 0 | return match committed.merge(rest) { |
1306 | 0 | Commit::Commit(()) => CommitOk(mem::take(output)), |
1307 | 0 | Commit::Peek(()) => PeekOk(mem::take(output)), |
1308 | | }; |
1309 | | } |
1310 | | Err(Commit::Peek(_)) => { |
1311 | 0 | ctry!(input.reset(before).committed()); |
1312 | 0 | mode.set_first(); |
1313 | 0 | *is_parse = true; |
1314 | | } |
1315 | 0 | Err(Commit::Commit(e)) => { |
1316 | 0 | ctry!(input.reset(before).committed()); |
1317 | 0 | return CommitErr(e.error); |
1318 | | } |
1319 | | } |
1320 | | } |
1321 | | } |
1322 | 0 | } |
1323 | | } |
1324 | | |
1325 | 0 | pub fn repeat_until<F, Input, P, E>(parser: P, end: E) -> RepeatUntil<F, P, E> |
1326 | 0 | where |
1327 | 0 | Input: Stream, |
1328 | 0 | F: Extend<P::Output> + Default, |
1329 | 0 | P: Parser<Input>, |
1330 | 0 | E: Parser<Input>, |
1331 | | { |
1332 | 0 | RepeatUntil { |
1333 | 0 | parser, |
1334 | 0 | end, |
1335 | 0 | _marker: PhantomData, |
1336 | 0 | } |
1337 | 0 | } |
1338 | | |
1339 | | parser! { |
1340 | | pub struct SkipRepeatUntil; |
1341 | | type PartialState = <With<RepeatUntil<Sink, P, E>, Value<Input, ()>> as Parser<Input>>::PartialState; |
1342 | | /// Skips input until `end` is encountered or `end` indicates that it has committed input before |
1343 | | /// failing (`attempt` can be used to continue skipping even if `end` has committed input) |
1344 | | /// |
1345 | | /// ``` |
1346 | | /// # extern crate combine; |
1347 | | /// # use combine::*; |
1348 | | /// # use combine::parser::char; |
1349 | | /// # use combine::parser::byte; |
1350 | | /// # use combine::parser::combinator::attempt; |
1351 | | /// # use combine::parser::repeat::skip_until; |
1352 | | /// # fn main() { |
1353 | | /// let mut char_parser = skip_until(char::digit()); |
1354 | | /// assert_eq!(char_parser.parse("abc123"), Ok(((), "123"))); |
1355 | | /// |
1356 | | /// let mut byte_parser = skip_until(byte::bytes(&b"TAG"[..])); |
1357 | | /// assert_eq!(byte_parser.parse(&b"123TAG"[..]), Ok(((), &b"TAG"[..]))); |
1358 | | /// assert!(byte_parser.parse(&b"123TATAG"[..]).is_err()); |
1359 | | /// |
1360 | | /// // `attempt` must be used because the `end` will commit to `TA` before failing, |
1361 | | /// // but we want to continue skipping |
1362 | | /// let mut byte_parser = skip_until(attempt(byte::bytes(&b"TAG"[..]))); |
1363 | | /// assert_eq!(byte_parser.parse(&b"123TATAG"[..]), Ok(((), &b"TAG"[..]))); |
1364 | | /// } |
1365 | | /// ``` |
1366 | | pub fn repeat_skip_until[Input, P, E](parser: P, end: E)(Input) -> () |
1367 | | where [ |
1368 | | P: Parser<Input>, |
1369 | | E: Parser<Input>, |
1370 | | ] |
1371 | | { |
1372 | | repeat_until::<Sink, _, _, _>(parser, end).with(value(())) |
1373 | | } |
1374 | | } |
1375 | | |
1376 | | #[derive(Default)] |
1377 | | pub struct EscapedState<T, U>(PhantomData<(T, U)>); |
1378 | | |
1379 | | pub struct Escaped<P, Q, I> { |
1380 | | parser: P, |
1381 | | escape: I, |
1382 | | escape_parser: Q, |
1383 | | } |
1384 | | impl<Input, P, Q> Parser<Input> for Escaped<P, Q, Input::Token> |
1385 | | where |
1386 | | Input: Stream, |
1387 | | P: Parser<Input>, |
1388 | | <Input as StreamOnce>::Token: PartialEq, |
1389 | | Q: Parser<Input>, |
1390 | | { |
1391 | | type Output = (); |
1392 | | type PartialState = EscapedState<P::PartialState, Q::PartialState>; |
1393 | | |
1394 | 0 | fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<Self::Output, Input::Error> { |
1395 | 0 | let mut committed = Commit::Peek(()); |
1396 | | loop { |
1397 | 0 | match self.parser.parse_lazy(input) { |
1398 | 0 | PeekOk(_) => {} |
1399 | 0 | CommitOk(_) => { |
1400 | 0 | committed = Commit::Commit(()); |
1401 | 0 | } |
1402 | | PeekErr(_) => { |
1403 | 0 | let checkpoint = input.checkpoint(); |
1404 | 0 | match uncons(input) { |
1405 | 0 | CommitOk(ref c) | PeekOk(ref c) if *c == self.escape => { |
1406 | 0 | match self.escape_parser.parse_committed_mode( |
1407 | 0 | FirstMode, |
1408 | 0 | input, |
1409 | 0 | &mut Default::default(), |
1410 | 0 | ) { |
1411 | 0 | PeekOk(_) => {} |
1412 | 0 | CommitOk(_) => { |
1413 | 0 | committed = Commit::Commit(()); |
1414 | 0 | } |
1415 | 0 | CommitErr(err) => return CommitErr(err), |
1416 | 0 | PeekErr(err) => { |
1417 | 0 | return CommitErr(err.error); |
1418 | | } |
1419 | | } |
1420 | | } |
1421 | 0 | CommitErr(err) => { |
1422 | 0 | return CommitErr(err); |
1423 | | } |
1424 | | _ => { |
1425 | 0 | ctry!(input.reset(checkpoint).committed()); |
1426 | 0 | return if committed.is_peek() { |
1427 | 0 | PeekOk(()) |
1428 | | } else { |
1429 | 0 | CommitOk(()) |
1430 | | }; |
1431 | | } |
1432 | | } |
1433 | | } |
1434 | 0 | CommitErr(err) => return CommitErr(err), |
1435 | | } |
1436 | | } |
1437 | 0 | } |
1438 | | |
1439 | 0 | fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) { |
1440 | | use crate::error; |
1441 | | |
1442 | 0 | self.parser.add_error(errors); |
1443 | | |
1444 | 0 | errors.error.add_expected(error::Token(self.escape.clone())); |
1445 | 0 | } |
1446 | | } |
1447 | | |
1448 | | /// Parses an escaped string by first applying `parser` which accept the normal characters which do |
1449 | | /// not need escaping. Once `parser` can not consume any more input it checks if the next token |
1450 | | /// is `escape`. If it is then `escape_parser` is used to parse the escaped character and then |
1451 | | /// resumes parsing using `parser`. If `escape` was not found then the parser finishes |
1452 | | /// successfully. |
1453 | | /// |
1454 | | /// This returns `()` since there isn't a good way to collect the output of the parsers so it is |
1455 | | /// best paired with one of the `recognize` parsers. |
1456 | | /// |
1457 | | /// ``` |
1458 | | /// # extern crate combine; |
1459 | | /// # use combine::*; |
1460 | | /// # use combine::parser::repeat::escaped; |
1461 | | /// # use combine::parser::char; |
1462 | | /// # use combine::parser::range::{recognize, take_while1}; |
1463 | | /// # fn main() { |
1464 | | /// let mut parser = recognize( |
1465 | | /// escaped(take_while1(|c| c != '"' && c != '\\'), '\\', one_of(r#"nr"\"#.chars())) |
1466 | | /// ); |
1467 | | /// assert_eq!(parser.parse(r#"ab\"12\n\rc""#), Ok((r#"ab\"12\n\rc"#, r#"""#))); |
1468 | | /// assert!(parser.parse(r#"\"#).is_err()); |
1469 | | /// assert!(parser.parse(r#"\a"#).is_err()); |
1470 | | /// } |
1471 | | /// ``` |
1472 | 0 | pub fn escaped<Input, P, Q>( |
1473 | 0 | parser: P, |
1474 | 0 | escape: <Input as StreamOnce>::Token, |
1475 | 0 | escape_parser: Q, |
1476 | 0 | ) -> Escaped<P, Q, Input::Token> |
1477 | 0 | where |
1478 | 0 | Input: Stream, |
1479 | 0 | P: Parser<Input>, |
1480 | 0 | <Input as StreamOnce>::Token: PartialEq, |
1481 | 0 | Q: Parser<Input>, |
1482 | | { |
1483 | 0 | Escaped { |
1484 | 0 | parser, |
1485 | 0 | escape, |
1486 | 0 | escape_parser, |
1487 | 0 | } |
1488 | 0 | } |
1489 | | |
1490 | | pub struct Iterate<F, I, P> { |
1491 | | parser: P, |
1492 | | iterable: I, |
1493 | | _marker: PhantomData<fn() -> F>, |
1494 | | } |
1495 | | impl<'s, 'a, P, Q, I, J, F> Parser<I> for Iterate<F, J, P> |
1496 | | where |
1497 | | P: FnMut(&J::Item, &mut I) -> Q, |
1498 | | Q: Parser<I>, |
1499 | | I: Stream, |
1500 | | J: IntoIterator + Clone, |
1501 | | F: Extend<Q::Output> + Default, |
1502 | | { |
1503 | | type Output = F; |
1504 | | type PartialState = ( |
1505 | | Option<(J::IntoIter, Option<J::Item>)>, |
1506 | | bool, |
1507 | | F, |
1508 | | Q::PartialState, |
1509 | | ); |
1510 | | |
1511 | | parse_mode!(I); |
1512 | | |
1513 | 0 | fn parse_mode_impl<M>( |
1514 | 0 | &mut self, |
1515 | 0 | mut mode: M, |
1516 | 0 | input: &mut I, |
1517 | 0 | state: &mut Self::PartialState, |
1518 | 0 | ) -> ParseResult<Self::Output, I::Error> |
1519 | 0 | where |
1520 | 0 | M: ParseMode, |
1521 | | { |
1522 | 0 | let (opt_iter, committed, buf, next) = state; |
1523 | 0 | let (iter, next_item) = match opt_iter { |
1524 | 0 | Some(iter) if !mode.is_first() => iter, |
1525 | | _ => { |
1526 | 0 | *opt_iter = Some((self.iterable.clone().into_iter(), None)); |
1527 | 0 | opt_iter.as_mut().unwrap() |
1528 | | } |
1529 | | }; |
1530 | | |
1531 | 0 | let mut consume = |item: J::Item| { |
1532 | 0 | let mut parser = (self.parser)(&item, input); |
1533 | 0 | let before = input.checkpoint(); |
1534 | 0 | match parser.parse_mode(mode, input, next) { |
1535 | 0 | PeekOk(v) => { |
1536 | 0 | mode.set_first(); |
1537 | 0 | Ok(v) |
1538 | | } |
1539 | 0 | CommitOk(v) => { |
1540 | 0 | mode.set_first(); |
1541 | 0 | *committed = true; |
1542 | 0 | Ok(v) |
1543 | | } |
1544 | 0 | PeekErr(err) => { |
1545 | 0 | if let Err(err) = input.reset(before) { |
1546 | 0 | return Err((item, CommitErr(err))); |
1547 | 0 | } |
1548 | | Err(( |
1549 | 0 | item, |
1550 | 0 | if *committed { |
1551 | 0 | CommitErr(err.error) |
1552 | | } else { |
1553 | 0 | PeekErr(err) |
1554 | | }, |
1555 | | )) |
1556 | | } |
1557 | 0 | CommitErr(err) => Err((item, CommitErr(err))), |
1558 | | } |
1559 | 0 | }; |
1560 | | |
1561 | 0 | let result = (|| { |
1562 | 0 | if let Some(item) = next_item.take() { |
1563 | 0 | buf.extend(Some(consume(item)?)); |
1564 | 0 | } |
1565 | 0 | let mut result = Ok(()); |
1566 | 0 | let size_hint = iter.size_hint(); |
1567 | 0 | buf.extend(suggest_size_hint( |
1568 | 0 | iter.scan((), |_, item| match consume(item) { |
1569 | 0 | Ok(item) => Some(item), |
1570 | 0 | Err(err) => { |
1571 | 0 | result = Err(err); |
1572 | 0 | None |
1573 | | } |
1574 | 0 | }), |
1575 | 0 | size_hint, |
1576 | | )); |
1577 | 0 | result |
1578 | | })(); |
1579 | | |
1580 | 0 | if let Err((item, err)) = result { |
1581 | 0 | *next_item = Some(item); |
1582 | 0 | return err; |
1583 | 0 | } |
1584 | | |
1585 | 0 | opt_iter.take(); |
1586 | | |
1587 | 0 | let value = mem::take(buf); |
1588 | 0 | if *committed { |
1589 | 0 | *committed = false; |
1590 | 0 | CommitOk(value) |
1591 | | } else { |
1592 | 0 | PeekOk(value) |
1593 | | } |
1594 | 0 | } |
1595 | | } |
1596 | | |
1597 | | /// |
1598 | | /// ``` |
1599 | | /// # use combine::parser::repeat::{count_min_max, iterate}; |
1600 | | /// # use combine::*; |
1601 | | /// |
1602 | | /// assert_eq!( |
1603 | | /// iterate(0..3, |&i, _| count_min_max(i, i, any())).parse("abbccc"), |
1604 | | /// Ok((vec!["".to_string(), "a".to_string(), "bb".to_string()], "ccc")), |
1605 | | /// ); |
1606 | | /// ``` |
1607 | 0 | pub fn iterate<F, J, P, I, Q>(iterable: J, parser: P) -> Iterate<F, J, P> |
1608 | 0 | where |
1609 | 0 | P: FnMut(&J::Item, &mut I) -> Q, |
1610 | 0 | Q: Parser<I>, |
1611 | 0 | I: Stream, |
1612 | 0 | J: IntoIterator + Clone, |
1613 | 0 | F: Extend<Q::Output> + Default, |
1614 | | { |
1615 | 0 | Iterate { |
1616 | 0 | parser, |
1617 | 0 | iterable, |
1618 | 0 | _marker: PhantomData, |
1619 | 0 | } |
1620 | 0 | } |