1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
use core::fmt;
use crate::{Text, TextChunk, TextConcat, SourceIterItem, SourceStream};
use crate::text::chunk::SourceStream as ChunkSourceStream;
use crate::parser::{DatumAllocator, AllocError};
pub mod chunks;
pub struct Iter<'l, TT>
where TT: Text,
{
cur_chunk_src_strm: Option<<TT::Chunk as TextChunk>::CharsSrcStrm>,
next_chunks_iter: chunks::Iter<'l, TT>,
accum: Option<TT>,
peeked: Option<SourceIterItem<TT::Pos>>,
}
impl<TT> fmt::Debug for Iter<'_, TT>
where TT: Text,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}::Iter", module_path!())
}
}
impl<'l, TT> Iter<'l, TT>
where TT: Text,
{
pub fn new(text: &'l TT) -> Self {
let mut next_chunks_iter = text.iter_chunks();
let cur_chunk_src_strm = next_chunks_iter.next().map(TextChunk::src_strm);
Self {
cur_chunk_src_strm,
next_chunks_iter,
accum: None,
peeked: None,
}
}
}
impl<'l, TT> Iterator for Iter<'l, TT>
where TT: Text,
TT::Chunk: 'l,
{
type Item = SourceIterItem<TT::Pos>;
fn next(&mut self) -> Option<Self::Item> {
self.accum = None;
self.peeked = None;
loop {
if let Some(ccss) = &mut self.cur_chunk_src_strm {
if let it @ Some(_) = ccss.next() {
break it
} else {
self.cur_chunk_src_strm
= self.next_chunks_iter.next().map(TextChunk::src_strm);
}
} else {
break None
}
}
}
}
impl<'l, TT, DA> SourceStream<DA> for Iter<'l, TT>
where TT: TextConcat<DA>,
TT::Chunk: 'l,
DA: DatumAllocator<TT = TT>,
{
fn peek(&mut self) -> Option<&<Self as Iterator>::Item> {
if let Some(ref it) = self.peeked {
return Some(it)
}
let mut cur_chunk_src_strm;
let mut cur_chunk_src_strm_ref = &mut self.cur_chunk_src_strm;
let mut next_chunks_iter = self.next_chunks_iter.clone();
loop {
if let Some(ccss) = cur_chunk_src_strm_ref {
if let Some(it) = ccss.peek() {
self.peeked = Some(it.clone());
break self.peeked.as_ref()
} else {
cur_chunk_src_strm
= next_chunks_iter.next().map(TextChunk::src_strm);
cur_chunk_src_strm_ref = &mut cur_chunk_src_strm;
}
} else {
break None
}
}
}
fn next_accum(&mut self, dalloc: &mut DA)
-> Result<Option<<Self as Iterator>::Item>,
AllocError>
{
self.peeked = None;
Ok(loop {
if let Some(ccss) = &mut self.cur_chunk_src_strm {
if let it @ Some(_) = ccss.next_accum() {
break it
} else {
let chunk_ended = ccss.accum_done().into();
self.accum = Some(self.accum.take().unwrap_or_else(TT::empty)
.concat(chunk_ended, dalloc)?);
self.cur_chunk_src_strm
= self.next_chunks_iter.next().map(TextChunk::src_strm);
}
} else {
break None
}
})
}
fn accum_done(&mut self, dalloc: &mut DA) -> Result<TT, AllocError> {
let mut accum = self.accum.take().unwrap_or_else(TT::empty);
if let Some(ccss) = &mut self.cur_chunk_src_strm {
let chunk_ended = ccss.accum_done().into();
accum = accum.concat(chunk_ended, dalloc)?;
}
Ok(accum)
}
}
#[cfg(test)]
mod tests {
}