mica/corelib/iterators/string/
split.rs

1use crate::{
2    builtin_traits::iterator, ll::value::RawValue, Engine, Error, Gc, TypeBuilder, UserData,
3};
4
5pub(crate) struct StringSplit {
6    string: RawValue,
7    separator: Gc<String>,
8    index: usize,
9}
10
11impl StringSplit {
12    pub unsafe fn new(s: RawValue, separator: Gc<String>) -> Self {
13        Self { string: s, separator, index: 0 }
14    }
15
16    fn has_next(&self) -> bool {
17        self.index < unsafe { self.string.get_raw_string_unchecked().get().len() }
18    }
19
20    fn next(&mut self) -> Option<String> {
21        unsafe {
22            let s = self.string.get_raw_string_unchecked().get();
23            let fragment = s[self.index..].split(&**self.separator).next();
24            if let Some(fragment) = fragment {
25                self.index += fragment.len();
26                self.index += self.separator.len();
27            }
28            fragment.map(String::from)
29        }
30    }
31}
32
33impl UserData for StringSplit {}
34
35pub(crate) fn load_string_split_iter(engine: &mut Engine) -> Result<(), Error> {
36    engine.add_type(
37        TypeBuilder::<StringSplit>::new("StringSplit")
38            .add_builtin_trait_function(iterator::HasNext, StringSplit::has_next)
39            .add_builtin_trait_function(iterator::Next, StringSplit::next),
40    )?;
41
42    Ok(())
43}