quickjs_runtime/quickjs_utils/
iterators.rs

1//! utils for the iterator protocol
2
3use crate::jsutils::JsError;
4use crate::quickjs_utils::{functions, objects, primitives};
5use crate::quickjsvalueadapter::QuickJsValueAdapter;
6use libquickjs_sys as q;
7
8/// iterate over an object conforming to the [iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterator_protocol) protocol
9/// # Safety
10/// please ensure that the QuickjsContext corresponding to the passed JSContext is still valid
11pub unsafe fn iterate<C: Fn(QuickJsValueAdapter) -> Result<R, JsError>, R>(
12    ctx: *mut q::JSContext,
13    iterator_ref: &QuickJsValueAdapter,
14    consumer_producer: C,
15) -> Result<Vec<R>, JsError> {
16    let mut res = vec![];
17
18    loop {
19        let next_obj = functions::invoke_member_function(ctx, iterator_ref, "next", &[])?;
20        if primitives::to_bool(&objects::get_property(ctx, &next_obj, "done")?)? {
21            break;
22        } else {
23            let next_item = objects::get_property(ctx, &next_obj, "value")?;
24            res.push(consumer_producer(next_item)?);
25        }
26    }
27
28    Ok(res)
29}