mica/corelib/iterators/string/
split.rs1use 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}