compose_library/foundations/iterator/
string_iter.rs1use compose_library::diag::SourceResult;
2use compose_library::vm::Vm;
3use compose_library::{IntoValue, Value, ValueIterator};
4use ecow::EcoString;
5use std::sync::{Arc, Mutex};
6
7#[derive(Debug, Clone)]
8pub struct StringIterator {
9 s: EcoString,
10 byte_pos: Arc<Mutex<usize>>,
11}
12
13impl PartialEq for StringIterator {
14 fn eq(&self, other: &Self) -> bool {
15 if self.s != other.s {
16 return false;
17 }
18
19 let pos_a = self.byte_pos.lock().expect("Poisoned");
21 let pos_b = self.byte_pos.lock().expect("Poisoned");
22
23 if *pos_a != *pos_b {
24 return false;
25 }
26
27 true
28 }
29}
30
31impl StringIterator {
32 pub fn new(s: EcoString) -> Self {
33 Self { s, byte_pos: Arc::new(Mutex::new(0)) }
34 }
35}
36
37impl ValueIterator for StringIterator {
38 fn next(&self, _: &mut dyn Vm) -> SourceResult<Option<Value>> {
39 let mut idx = self.byte_pos.lock().expect("Poisoned");
40
41 if *idx >= self.s.len() {
42 return Ok(None);
43 }
44
45 let Some(c) = self.s[*idx..].chars().next() else {
46 return Ok(None)
47 };
48
49 *idx += c.len_utf8();
50
51 Ok(Some(c.into_value()))
52 }
53}