Skip to main content

field_collex/collex/
iter.rs

1use crate::collex::CollexField;
2use crate::{Collexetable, Field, FieldCollex, FieldValue, RawField};
3
4// ========== 无 dyn 动态分发的不可变迭代器 ==========
5/// 递归迭代栈的元素类型(静态类型,无动态分发)
6enum IterStackItem<'a, E, V>
7where
8    E: Collexetable<V>,
9    V: FieldValue,
10{
11    // 外层 items 的迭代器
12    Outer(std::slice::Iter<'a, CollexField<E, V>>),
13    // 子 Collex 的迭代器
14    Inner(Iter<'a, E, V>),
15}
16
17/// `FieldCollex` 的不可变迭代器(纯静态类型,无 dyn)
18pub struct Iter<'a, E, V>
19where
20    E: Collexetable<V>,
21    V: FieldValue,
22{
23    // 静态类型的迭代栈(替代 dyn 动态分发)
24    stack: Vec<IterStackItem<'a, E, V>>,
25}
26
27impl<'a, E, V> Iter<'a, E, V>
28where
29    E: Collexetable<V>,
30    V: FieldValue,
31{
32    /// 构造引用迭代器(内部调用)
33    pub(crate) fn new(collex: &'a FieldCollex<E, V>) -> Self {
34        Self {
35            stack: vec![IterStackItem::Outer(collex.items.iter())],
36        }
37    }
38}
39
40
41impl<E, V> FieldCollex<E, V>
42where
43    E: Collexetable<V>,
44    V: FieldValue,
45{
46    /// 获取不可变迭代器
47    pub fn iter(&self) -> Iter<'_, E, V> {
48        Iter {
49            stack: vec![IterStackItem::Outer(self.items.iter())],
50        }
51    }
52}
53
54// ========== 纯静态类型的 Iterator trait 实现 ==========
55impl<'a, E, V> Iterator for Iter<'a, E, V>
56where
57    E: Collexetable<V>,
58    V: FieldValue,
59{
60    type Item = &'a E;
61    
62    fn next(&mut self) -> Option<Self::Item> {
63        // 从栈顶取出迭代器处理(栈式递归)
64        while let Some(mut iter_item) = self.stack.pop() {
65            match &mut iter_item {
66                // 处理外层 items 迭代器
67                IterStackItem::Outer(outer_iter) => {
68                    while let Some(field) = outer_iter.next() {
69                        match field {
70                            RawField::Thing((_, field)) => match field {
71                                // 单个元素,直接返回
72                                Field::Elem(e) => {
73                                    // 把当前外层迭代器放回栈(后续继续处理)
74                                    self.stack.push(iter_item);
75                                    return Some(e);
76                                }
77                                // 子 Collex,创建子迭代器并压入栈(优先处理子迭代器)
78                                Field::Collex(collex) => {
79                                    // 先把当前外层迭代器放回栈
80                                    self.stack.push(iter_item);
81                                    // 把子 Collex 迭代器压入栈(栈顶优先处理)
82                                    self.stack.push(IterStackItem::Inner(collex.iter()));
83                                    // 重新进入循环,处理子迭代器
84                                    break;
85                                }
86                            },
87                            // 空块,跳过
88                            _ => continue,
89                        }
90                    }
91                    // 外层迭代器处理完,无需放回栈
92                }
93                // 处理子 Collex 迭代器
94                IterStackItem::Inner(inner_iter) => {
95                    if let Some(item) = inner_iter.next() {
96                        // 子迭代器未处理完,放回栈
97                        self.stack.push(iter_item);
98                        return Some(item);
99                    }
100                    // 子迭代器处理完,无需放回栈
101                }
102            }
103        }
104        
105        // 所有迭代器处理完毕
106        None
107    }
108}
109
110#[derive(Debug)]
111pub enum IntoIterStackItem<E, V>
112where
113    E: Collexetable<V>,
114    V: FieldValue,
115{
116    // 持有 vec::IntoIter 所有权(消耗型,不可克隆)
117    Outer(std::vec::IntoIter<CollexField<E, V>>),
118    // 持有子 Collex 的 IntoIter 所有权
119    Inner(IntoIter<E, V>),
120}
121
122#[derive(Debug)]
123pub struct IntoIter<E, V>
124where
125    E: Collexetable<V>,
126    V: FieldValue,
127{
128    stack: Vec<IntoIterStackItem<E, V>>,
129}
130
131impl<E, V> IntoIter<E, V>
132where
133    E: Collexetable<V>,
134    V: FieldValue,
135{
136    pub(crate) fn new(collex: FieldCollex<E, V>) -> Self {
137        // 转移 items 所有权到 vec::IntoIter(消耗原 FieldCollex 的 items)
138        let outer_iter = collex.items.into_iter();
139        Self {
140            stack: vec![IntoIterStackItem::Outer(outer_iter)],
141        }
142    }
143}
144
145// 核心修复:无克隆、真正消耗所有权的 Iterator 实现
146impl<E, V> Iterator for IntoIter<E, V>
147where
148    E: Collexetable<V>,
149    V: FieldValue,
150{
151    type Item = E;
152    
153    fn next(&mut self) -> Option<Self::Item> {
154        // 循环处理栈顶迭代器(所有权转移)
155        while let Some(mut iter_item) = self.stack.pop() {
156            match &mut iter_item {
157                IntoIterStackItem::Outer(outer_iter) => {
158                    // 遍历外层迭代器(消耗式)
159                    while let Some(field) = outer_iter.next() {
160                        match field {
161                            RawField::Thing((_, field_in)) => match field_in {
162                                // 匹配到元素:直接返回所有权,同时把剩余迭代器放回栈
163                                Field::Elem(e) => {
164                                    // 把「剩余未处理的外层迭代器」放回栈(无克隆,转移剩余所有权)
165                                    self.stack.push(IntoIterStackItem::Outer(std::mem::take(outer_iter)));
166                                    return Some(e);
167                                }
168                                // 匹配到子 Collex:转移子 Collex 所有权,创建子迭代器压栈
169                                Field::Collex(collex) => {
170                                    // 1. 把当前剩余的外层迭代器放回栈
171                                    self.stack.push(IntoIterStackItem::Outer(std::mem::take(outer_iter)));
172                                    // 2. 把子 Collex 迭代器压入栈(优先处理子迭代器)
173                                    self.stack.push(IntoIterStackItem::Inner(IntoIter::new(collex)));
174                                    // 跳出当前循环,处理子迭代器
175                                    break;
176                                }
177                            },
178                            // 空块:跳过,继续遍历外层迭代器
179                            RawField::Prev(_) | RawField::Among(_, _) | RawField::Next(_) | RawField::Void => continue,
180                        }
181                    }
182                    // 外层迭代器已耗尽,无需放回栈
183                }
184                IntoIterStackItem::Inner(inner_iter) => {
185                    // 处理子迭代器(消耗式)
186                    if let Some(item) = inner_iter.next() {
187                        // 子迭代器未耗尽,放回栈继续处理
188                        self.stack.push(iter_item);
189                        return Some(item);
190                    }
191                    // 子迭代器已耗尽,无需放回栈
192                }
193            }
194        }
195        // 所有迭代器处理完毕
196        None
197    }
198}
199
200/// FieldCollex 所有权转移的 IntoIterator 实现(核心:消耗 self)
201impl<E, V> IntoIterator for FieldCollex<E, V>
202where
203    E: Collexetable<V>,
204    V: FieldValue,
205{
206    type Item = E;
207    type IntoIter = IntoIter<E, V>;
208    
209    fn into_iter(self) -> Self::IntoIter {
210        IntoIter::new(self)
211    }
212}
213
214impl<'a, E, V> IntoIterator for &'a FieldCollex<E, V>
215where
216    E: Collexetable<V>,
217    V: FieldValue,
218{
219    type Item = &'a E;
220    type IntoIter = Iter<'a, E, V>;
221    
222    fn into_iter(self) -> Self::IntoIter {
223        Iter::new(self)
224    }
225}
226
227#[cfg(test)]
228mod tests {
229    use super::*;
230    use span_core::Span;
231    
232    // ===================== 测试用元素类型(实现Collexetable<u32>) =====================
233    #[derive(Debug, PartialEq, Eq, Ord, PartialOrd)]
234    #[derive(Clone)]
235struct TestElem(u32);
236    
237    impl Collexetable<u32> for TestElem {
238        fn collexate(&self) -> u32 {
239            self.0
240        }
241        
242        fn collexate_ref(&self) -> &u32 {
243            &self.0
244        }
245        
246        fn collexate_mut(&mut self) -> &mut u32 {
247            &mut self.0
248        }
249    }
250    #[test]
251    fn test_iter() {
252        let span = Span::new_finite(0u32, 100u32);
253        let unit = 20u32;
254        let elems = vec![TestElem(5), TestElem(15), TestElem(25), TestElem(55)];
255        let collex = FieldCollex::<TestElem, u32>::with_elements(span, unit, elems).unwrap();
256        
257        // 遍历验证顺序和内容
258        let collected: Vec<_> = collex.iter().cloned().collect();
259        assert_eq!(collected, vec![TestElem(5), TestElem(15), TestElem(25), TestElem(55)]);
260        
261        // for 循环遍历(IntoIterator)
262        let mut values = Vec::new();
263        for elem in &collex {
264            values.push(elem.0);
265        }
266        assert_eq!(values, vec![5, 15, 25, 55]);
267        
268        // 空集合迭代器
269        let empty_collex = FieldCollex::<TestElem, u32>::new(Span::new_finite(0u32, 100u32), 10u32).unwrap();
270        assert!(empty_collex.iter().next().is_none());
271    }
272}