1use super::*;
2
3pub struct Stream<I: Iterator> {
11 tokens: Vec<I::Item>,
12 iter: I,
13}
14
15impl<I: Iterator> Stream<I> {
16 pub fn from_iter<J: IntoIterator<IntoIter = I>>(iter: J) -> Self {
29 Self {
30 tokens: Vec::new(),
31 iter: iter.into_iter(),
32 }
33 }
34
35 pub fn boxed<'a>(self) -> BoxedStream<'a, I::Item>
38 where
39 I: 'a,
40 {
41 Stream {
42 tokens: self.tokens,
43 iter: Box::new(self.iter),
44 }
45 }
46
47 pub fn exact_size_boxed<'a>(self) -> BoxedExactSizeStream<'a, I::Item>
49 where
50 I: ExactSizeIterator + 'a,
51 {
52 Stream {
53 tokens: self.tokens,
54 iter: Box::new(self.iter),
55 }
56 }
57}
58
59pub type BoxedStream<'a, T> = Stream<Box<dyn Iterator<Item = T> + 'a>>;
61
62pub type BoxedExactSizeStream<'a, T> = Stream<Box<dyn ExactSizeIterator<Item = T> + 'a>>;
64
65impl<I: Iterator> Sealed for Stream<I> {}
66impl<'src, I: Iterator + 'src> Input<'src> for Stream<I>
67where
68 I::Item: Clone,
69{
70 type Span = SimpleSpan<usize>;
71
72 type Token = I::Item;
73 type MaybeToken = I::Item;
74
75 type Cursor = usize;
76
77 type Cache = Self;
78
79 #[inline(always)]
80 fn begin(self) -> (Self::Cursor, Self::Cache) {
81 (0, self)
82 }
83
84 #[inline]
85 fn cursor_location(cursor: &Self::Cursor) -> usize {
86 *cursor
87 }
88
89 #[inline(always)]
90 unsafe fn next_maybe(
91 this: &mut Self::Cache,
92 cursor: &mut Self::Cursor,
93 ) -> Option<Self::MaybeToken> {
94 Self::next(this, cursor)
95 }
96
97 #[inline(always)]
98 unsafe fn span(_this: &mut Self::Cache, range: Range<&Self::Cursor>) -> Self::Span {
99 (*range.start..*range.end).into()
100 }
101}
102
103impl<'src, I: ExactSizeIterator + 'src> ExactSizeInput<'src> for Stream<I>
104where
105 I::Item: Clone,
106{
107 #[inline(always)]
108 unsafe fn span_from(this: &mut Self::Cache, range: RangeFrom<&Self::Cursor>) -> Self::Span {
109 (*range.start..this.tokens.len() + this.iter.len()).into()
110 }
111}
112
113impl<'src, I: Iterator + 'src> ValueInput<'src> for Stream<I>
114where
115 I::Item: Clone,
116{
117 #[inline]
118 unsafe fn next(this: &mut Self::Cache, cursor: &mut Self::Cursor) -> Option<Self::Token> {
119 if this.tokens.len() <= *cursor {
121 this.tokens.extend((&mut this.iter).take(512));
122 }
123
124 this.tokens.get(*cursor).map(|tok| {
126 *cursor += 1;
127 tok.clone()
128 })
129 }
130}
131
132pub struct IterInput<I, S> {
138 iter: I,
139 eoi: S,
140}
141
142impl<I, S> IterInput<I, S> {
143 pub fn new(iter: I, eoi: S) -> Self {
145 Self { iter, eoi }
146 }
147}
148
149impl<'src, I, T: 'src, S> Input<'src> for IterInput<I, S>
150where
151 I: Iterator<Item = (T, S)> + Clone + 'src,
152 S: Span + 'src,
153{
154 type Cursor = (I, usize, Option<S::Offset>);
155 type Span = S;
156
157 type Token = T;
158 type MaybeToken = T;
159
160 type Cache = S; #[inline]
163 fn begin(self) -> (Self::Cursor, Self::Cache) {
164 ((self.iter, 0, None), self.eoi)
165 }
166
167 #[inline]
168 fn cursor_location(cursor: &Self::Cursor) -> usize {
169 cursor.1
170 }
171
172 unsafe fn next_maybe(
173 _eoi: &mut Self::Cache,
174 cursor: &mut Self::Cursor,
175 ) -> Option<Self::MaybeToken> {
176 cursor.0.next().map(|(tok, span)| {
177 cursor.1 += 1;
178 cursor.2 = Some(span.end());
179 tok
180 })
181 }
182
183 unsafe fn span(eoi: &mut Self::Cache, range: Range<&Self::Cursor>) -> Self::Span {
184 match range.start.0.clone().next() {
185 Some((_, s)) => {
186 let end = range.end.2.clone().unwrap_or_else(|| eoi.end());
187 S::new(eoi.context(), s.start()..end)
188 }
189 None => S::new(eoi.context(), eoi.end()..eoi.end()),
190 }
191 }
192}
193
194impl<'src, I, T: 'src, S> ValueInput<'src> for IterInput<I, S>
206where
207 I: Iterator<Item = (T, S)> + Clone + 'src,
208 S: Span + 'src,
209{
210 #[inline]
211 unsafe fn next(this: &mut Self::Cache, cursor: &mut Self::Cursor) -> Option<Self::Token> {
212 Self::next_maybe(this, cursor)
213 }
214}
215
216#[test]
217fn map_tuple() {
218 fn parser<'src, I: Input<'src, Token = char>>() -> impl Parser<'src, I, char> {
219 just('h')
220 }
221
222 let stream = Stream::from_iter(core::iter::once(('h', 0..1))).boxed();
223 let stream = stream.map(0..10, |(t, s)| (t, s));
224
225 assert_eq!(parser().parse(stream).into_result(), Ok('h'));
226}