xee_interpreter/sequence/
iter.rs1use xot::Xot;
2
3use crate::{atomic, error, function};
4
5use super::item::Item;
6
7pub struct NodeIter<I>
9where
10 I: Iterator<Item = Item>,
11{
12 iter: I,
13}
14
15impl<I> NodeIter<I>
16where
17 I: Iterator<Item = Item>,
18{
19 pub(crate) fn new(iter: I) -> Self {
20 Self { iter }
21 }
22}
23
24impl<I> Iterator for NodeIter<I>
25where
26 I: Iterator<Item = Item>,
27{
28 type Item = error::Result<xot::Node>;
29
30 fn next(&mut self) -> Option<Self::Item> {
31 let next = self.iter.next();
32 next.map(|v| v.to_node())
33 }
34
35 fn size_hint(&self) -> (usize, Option<usize>) {
36 self.iter.size_hint()
37 }
38}
39
40pub struct AtomizedIter<'a, I>
42where
43 I: Iterator<Item = Item> + 'a,
44{
45 xot: &'a Xot,
46 iter: I,
47 item_iter: Option<AtomizedItemIter<'a>>,
48}
49
50impl<'a, I> AtomizedIter<'a, I>
51where
52 I: Iterator<Item = Item>,
53{
54 pub(crate) fn new(xot: &'a Xot, iter: I) -> AtomizedIter<'a, I> {
55 AtomizedIter {
56 xot,
57 iter,
58 item_iter: None,
59 }
60 }
61}
62
63impl<'a, I> Iterator for AtomizedIter<'a, I>
64where
65 I: Iterator<Item = Item> + 'a,
66{
67 type Item = error::Result<atomic::Atomic>;
68
69 fn next(&mut self) -> Option<error::Result<atomic::Atomic>> {
70 loop {
71 if let Some(item_iter) = &mut self.item_iter {
74 if let Some(item) = item_iter.next() {
75 return Some(item);
76 } else {
77 self.item_iter = None;
78 }
79 }
80 let item = self.iter.next();
82 if let Some(item) = item {
83 self.item_iter = Some(AtomizedItemIter::new(item, self.xot));
84 continue;
85 } else {
86 return None;
88 }
89 }
90 }
91
92 fn size_hint(&self) -> (usize, Option<usize>) {
93 let (lower, _) = self.iter.size_hint();
97 (lower, None)
98 }
99}
100
101pub enum AtomizedItemIter<'a> {
103 Atomic(std::iter::Once<atomic::Atomic>),
104 Node(AtomizedNodeIter),
105 Array(AtomizedArrayIter<'a>),
106 Erroring(std::iter::Once<error::Result<atomic::Atomic>>),
108}
109
110impl<'a> AtomizedItemIter<'a> {
111 pub(crate) fn new(item: Item, xot: &'a Xot) -> Self {
112 match item {
113 Item::Atomic(a) => Self::Atomic(std::iter::once(a)),
114 Item::Node(n) => Self::Node(AtomizedNodeIter::new(n, xot)),
115 Item::Function(function) => match function {
116 function::Function::Array(a) => Self::Array(AtomizedArrayIter::new(a, xot)),
117 _ => Self::Erroring(std::iter::once(Err(error::Error::FOTY0013))),
118 },
119 }
120 }
121}
122
123impl Iterator for AtomizedItemIter<'_> {
124 type Item = error::Result<atomic::Atomic>;
125
126 fn next(&mut self) -> Option<Self::Item> {
127 match self {
128 Self::Atomic(iter) => iter.next().map(Ok),
129 Self::Node(iter) => iter.next().map(Ok),
130 Self::Array(iter) => iter.next(),
131 Self::Erroring(iter) => iter.next(),
132 }
133 }
134
135 fn size_hint(&self) -> (usize, Option<usize>) {
136 match self {
137 Self::Atomic(iter) => iter.size_hint(),
138 Self::Node(iter) => iter.size_hint(),
139 Self::Array(iter) => iter.size_hint(),
140 Self::Erroring(iter) => iter.size_hint(),
141 }
142 }
143}
144
145pub struct AtomizedNodeIter {
147 typed_value: Vec<atomic::Atomic>,
148 typed_value_index: usize,
149}
150
151impl AtomizedNodeIter {
152 fn new(node: xot::Node, xot: &Xot) -> Self {
153 let s = xot.string_value(node);
154 let typed_value = vec![atomic::Atomic::Untyped(s.into())];
155 Self {
156 typed_value,
157 typed_value_index: 0,
158 }
159 }
160}
161
162impl Iterator for AtomizedNodeIter {
163 type Item = atomic::Atomic;
164
165 fn next(&mut self) -> Option<Self::Item> {
166 if self.typed_value_index < self.typed_value.len() {
167 let item = self.typed_value[self.typed_value_index].clone();
168 self.typed_value_index += 1;
169 Some(item)
170 } else {
171 None
172 }
173 }
174
175 fn size_hint(&self) -> (usize, Option<usize>) {
176 let remaining = self.typed_value.len() - self.typed_value_index;
177 (remaining, Some(remaining))
178 }
179}
180
181pub struct AtomizedArrayIter<'a> {
183 xot: &'a Xot,
184 array: function::Array,
185 array_index: usize,
186 iter: Option<std::vec::IntoIter<error::Result<atomic::Atomic>>>,
187}
188
189impl<'a> AtomizedArrayIter<'a> {
190 fn new(array: function::Array, xot: &'a Xot) -> Self {
191 Self {
192 xot,
193 array,
194 array_index: 0,
195 iter: None,
196 }
197 }
198}
199
200impl Iterator for AtomizedArrayIter<'_> {
201 type Item = error::Result<atomic::Atomic>;
202
203 fn next(&mut self) -> Option<Self::Item> {
204 loop {
205 if let Some(iter) = &mut self.iter {
208 if let Some(item) = iter.next() {
209 return Some(item);
210 } else {
211 self.iter = None;
212 }
213 }
214 let array = &self.array.0;
215 if self.array_index >= array.len() {
217 return None;
218 }
219 let sequence = &array[self.array_index];
220 self.array_index += 1;
221 let v = sequence.atomized(self.xot).collect::<Vec<_>>();
226 self.iter = Some(v.into_iter());
227 }
228 }
229
230 fn size_hint(&self) -> (usize, Option<usize>) {
231 let remaining = self.array.0.len() - self.array_index;
234 (remaining, None)
235 }
236}
237
238pub(crate) fn one<'a, T>(mut iter: impl Iterator<Item = T> + 'a) -> error::Result<T> {
239 if let Some(one) = iter.next() {
240 if iter.next().is_none() {
241 Ok(one)
242 } else {
243 Err(error::Error::XPTY0004)
244 }
245 } else {
246 Err(error::Error::XPTY0004)
247 }
248}
249
250pub(crate) fn option<'a, T>(mut iter: impl Iterator<Item = T> + 'a) -> error::Result<Option<T>> {
251 if let Some(one) = iter.next() {
252 if iter.next().is_none() {
253 Ok(Some(one))
254 } else {
255 Err(error::Error::XPTY0004)
256 }
257 } else {
258 Ok(None)
259 }
260}