This repository has been archived on 2025-08-04. You can view files and clone it, but cannot push or open issues or pull requests.
rhaj/_archive/rhai_engine/rhaibook/language/iterator.md
2025-04-04 08:28:07 +02:00

1.6 KiB

Make a Custom Type Iterable

{{#include ../links.md}}


Type iterators are already defined for built-in [standard types] such as [strings], [ranges],
[bit-fields], [arrays] and [object maps].

That's why they can be used with the [`for`] loop.

If a [custom type] is iterable, the [for] loop can be used to iterate through its items in sequence, as long as it has a type iterator registered.

Engine::register_iterator<T> allows registration of a type iterator for any type that implements IntoIterator.

With a type iterator registered, the [custom type] can be iterated through.

// Custom type
#[derive(Debug, Clone)]
struct TestStruct { fields: Vec<i64> }

// Implement 'IntoIterator' trait
impl IntoIterator<Item = i64> for TestStruct {
    type Item = i64;
    type IntoIter = std::vec::IntoIter<Self::Item>;

    fn into_iter(self) -> Self::IntoIter {
        self.fields.into_iter()
    }
}

let mut engine = Engine::new();

// Register API and type iterator for 'TestStruct'
engine.register_type_with_name::<TestStruct>("TestStruct")
      .register_fn("new_ts", || TestStruct { fields: vec![1, 2, 3, 42] })
      .register_iterator::<TestStruct>();

// 'TestStruct' is now iterable
engine.run(
"
    for value in new_ts() {
        ...
    }
")?;

`Engine::register_iterator_result` allows registration of a _fallible_ type iterator &ndash;
i.e. an iterator that returns `Result<T, Box<EvalAltResult>>`.

On in very rare situations will this be necessary though.