compose_library/foundations/iterator/
array_iter.rs1use crate::{Array, Trace};
2use compose_library::{UntypedRef, Value, ValueIterator, Vm};
3use ecow::EcoVec;
4use std::sync::{Arc, Mutex};
5use compose_library::diag::SourceResult;
6
7#[derive(Debug, Clone)]
8pub struct ArrayIter {
9 arr: EcoVec<Value>,
10 index: Arc<Mutex<usize>>,
11}
12
13impl PartialEq for ArrayIter {
14 fn eq(&self, other: &Self) -> bool {
15 if self.arr != other.arr {
16 return false;
17 }
18
19 let pos_a = self.index.lock().expect("Poisoned");
21 let pos_b = self.index.lock().expect("Poisoned");
22
23 if *pos_a != *pos_b {
24 return false;
25 }
26
27 true
28 }
29}
30
31impl ArrayIter {
32 pub fn new(arr: &Array) -> Self {
33 Self {
34 arr: EcoVec::from(arr.values.as_slice()),
35 index: Arc::new(Mutex::new(0)),
36 }
37 }
38
39}
40
41impl From<EcoVec<Value>> for ArrayIter {
42 fn from(arr: EcoVec<Value>) -> Self {
43 Self {
44 arr,
45 index: Arc::new(Mutex::new(0)),
46 }
47 }
48}
49
50impl ValueIterator for ArrayIter {
51 fn next(&self, vm: &mut dyn Vm) -> SourceResult<Option<Value>> {
52 self.nth(vm, 0)
53 }
54
55 fn nth(&self, _: &mut dyn Vm, n: usize) -> SourceResult<Option<Value>> {
56 let mut idx = self.index.lock().expect("Poisoned");
57
58 let new_idx = *idx + n;
59
60 if new_idx >= self.arr.len() {
61 return Ok(None);
62 }
63
64 let item = &self.arr[new_idx];
65
66 *idx = new_idx + 1; Ok(Some(item.clone()))
69 }
70}
71
72impl Trace for ArrayIter {
73 fn visit_refs(&self, f: &mut dyn FnMut(UntypedRef)) {
74 for item in &self.arr {
75 item.visit_refs(f);
76 }
77 }
78}