Coverage Report

Created: 2026-01-09 06:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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>::next
Line
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>::next
Line
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_hint
Line
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_hint
Line
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_error
Line
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>>::new
Line
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>>::new
Line
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>::next
Line
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>::next
Line
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
}