mumu-array 0.1.2

Array tools plugin for the MuMu/Lava language
Documentation
use mumu::parser::types::{Value, InkIteratorKind};
use mumu::parser::interpreter::Interpreter;

pub fn array_collect_bridge(
    interp: &mut Interpreter,
    args: Vec<Value>
) -> Result<Value, String> {
    if interp.is_verbose() {
        eprintln!("[array:collect] called with args = {:?}", args);
    }
    if args.len() != 1 {
        if interp.is_verbose() {
            eprintln!("[array:collect] ERROR: Expected 1 argument, got {}", args.len());
        }
        return Err("array:collect => expected 1 argument".to_string());
    }
    match &args[0] {
        // Already a normal array type, just return as-is
        Value::IntArray(_) | Value::StrArray(_) | Value::BoolArray(_) | Value::FloatArray(_) | Value::MixedArray(_) => {
            if interp.is_verbose() {
                eprintln!("[array:collect] argument is already an array, returning as-is: {:?}", args[0]);
            }
            Ok(args[0].clone())
        }
        Value::InkIterator(h) => {
            match &h.kind {
                InkIteratorKind::Core(state_arc) => {
                    let mut out = Vec::new();
                    let mut guard = state_arc.lock().map_err(|_| "array:collect => cannot lock iterator".to_string())?;
                    let mut count = 0;
                    if interp.is_verbose() {
                        eprintln!("[array:collect] (Core) Beginning to collect from Core InkIterator. Start={}, End={}", guard.current, guard.end);
                    }
                    while !guard.done && guard.current < guard.end {
                        let next_val = guard.current;
                        guard.current += 1;
                        if guard.current >= guard.end {
                            guard.done = true;
                        }
                        out.push(Value::Int(next_val));
                        count += 1;
                        if interp.is_verbose() {
                            eprintln!("[array:collect] (Core) Collected int value: {}", next_val);
                        }
                    }
                    if interp.is_verbose() {
                        eprintln!("[array:collect] (Core) Finished collecting. Total items = {}", count);
                        eprintln!("[array:collect] (Core) Final output: {:?}", out);
                    }
                    Ok(Value::MixedArray(out))
                }
                InkIteratorKind::Plugin(plugin_arc) => {
                    let mut out = Vec::new();
                    let mut plugin = plugin_arc.lock().map_err(|_| "array:collect => cannot lock plugin iterator".to_string())?;
                    let mut count = 0;
                    if interp.is_verbose() {
                        eprintln!("[array:collect] (Plugin) Beginning to collect from Plugin InkIterator");
                    }
                    loop {
                        match plugin.next_value() {
                            Ok(v) => {
                                count += 1;
                                if interp.is_verbose() {
                                    eprintln!("[array:collect] (Plugin) Collected: {:?}", v);
                                }
                                out.push(v)
                            }
                            Err(e) if e == "NO_MORE_DATA" => {
                                if interp.is_verbose() {
                                    eprintln!("[array:collect] (Plugin) NO_MORE_DATA after {} items", count);
                                    eprintln!("[array:collect] (Plugin) Final output: {:?}", out);
                                }
                                break
                            }
                            Err(e) => {
                                if interp.is_verbose() {
                                    eprintln!("[array:collect] (Plugin) Error: {}", e);
                                }
                                return Err(format!("array:collect => plugin error: {}", e));
                            }
                        }
                    }
                    Ok(Value::MixedArray(out))
                }
            }
        }
        other => {
            if interp.is_verbose() {
                eprintln!("[array:collect] argument is not array or iterator: {:?}", other);
            }
            Err(format!("array:collect => not an array or iterator: {:?}", other))
        }
    }
}