use mumu::parser::interpreter::Interpreter;
use mumu::parser::types::{IteratorKind, Value};
pub fn array_collect_bridge(_interp: &mut Interpreter, mut args: Vec<Value>) -> Result<Value, String> {
if args.len() != 1 {
return Err(format!("array:collect expects exactly 1 argument, got {}", args.len()));
}
let v = args.remove(0);
match v {
Value::IntArray(xs) => Ok(Value::IntArray(xs)),
Value::FloatArray(xs) => Ok(Value::FloatArray(xs)),
Value::StrArray(xs) => Ok(Value::StrArray(xs)),
Value::BoolArray(xs) => Ok(Value::BoolArray(xs)),
Value::MixedArray(xs) => Ok(Value::MixedArray(xs)),
Value::Iterator(handle) => {
match &handle.kind {
IteratorKind::Core(state_arc) => {
let mut guard = state_arc
.lock()
.map_err(|_| "IteratorState lock error".to_string())?;
let mut out: Vec<i32> = Vec::new();
while !guard.done && guard.current < guard.end {
let next = guard.current;
guard.current += 1;
if guard.current >= guard.end {
guard.done = true;
}
out.push(next);
}
Ok(Value::IntArray(out))
}
IteratorKind::Plugin(plugin_arc) => {
let mut plugin = plugin_arc
.lock()
.map_err(|_| "Plugin Iterator lock error".to_string())?;
let mut items: Vec<Value> = Vec::new();
loop {
match plugin.next_value() {
Ok(val) => items.push(val),
Err(e) if e == "NO_MORE_DATA" => break,
Err(e) => return Err(format!("array:collect => {}", e)),
}
}
if items.iter().all(|v| matches!(v, Value::Int(_))) {
Ok(Value::IntArray(
items
.into_iter()
.map(|v| if let Value::Int(i) = v { i } else { unreachable!() })
.collect(),
))
} else if items.iter().all(|v| matches!(v, Value::Float(_))) {
Ok(Value::FloatArray(
items
.into_iter()
.map(|v| if let Value::Float(f) = v { f } else { unreachable!() })
.collect(),
))
} else if items.iter().all(|v| matches!(v, Value::SingleString(_))) {
Ok(Value::StrArray(
items
.into_iter()
.map(|v| if let Value::SingleString(s) = v { s } else { unreachable!() })
.collect(),
))
} else if items.iter().all(|v| matches!(v, Value::Bool(_))) {
Ok(Value::BoolArray(
items
.into_iter()
.map(|v| if let Value::Bool(b) = v { b } else { unreachable!() })
.collect(),
))
} else {
Ok(Value::MixedArray(items))
}
}
}
}
other => Err(format!("array:collect => unsupported input: {:?}", other)),
}
}