array-mumu 0.2.0-rc.5

Array tools plugin for the Mumu ecosystem
Documentation
use mumu::parser::types::Value;
use mumu::parser::interpreter::Interpreter;
use super::common::{is_placeholder, make_two_arg_partial};

pub fn array_pluck_bridge(interp: &mut Interpreter, args: Vec<Value>) -> Result<Value, String> {
    match args.len() {
        0 => Ok(make_two_arg_partial(do_pluck, None, None, "array-transform-pluck-partial")),
        1 => {
            if is_placeholder(&args[0]) {
                Ok(make_two_arg_partial(do_pluck, None, None, "array-transform-pluck-partial"))
            } else {
                Ok(make_two_arg_partial(do_pluck, Some(args[0].clone()), None, "array-transform-pluck-partial"))
            }
        }
        2 => {
            let a1_pl = is_placeholder(&args[0]);
            let a2_pl = is_placeholder(&args[1]);
            if !a1_pl && !a2_pl {
                do_pluck(interp, args[0].clone(), args[1].clone())
            } else {
                Ok(make_two_arg_partial(
                    do_pluck,
                    if a1_pl { None } else { Some(args[0].clone()) },
                    if a2_pl { None } else { Some(args[1].clone()) },
                    "array-transform-pluck-partial"
                ))
            }
        }
        _ => Err("array:pluck expects 2 arguments (key, array)".to_string()),
    }
}

fn do_pluck(_interp: &mut Interpreter, key: Value, arr: Value) -> Result<Value, String> {
    let key_str = match key {
        Value::SingleString(s) => s,
        Value::StrArray(a) if a.len() == 1 => a[0].clone(),
        _ => return Err("array:pluck => first argument must be a string key".to_string()),
    };
    match arr {
        Value::MixedArray(items) => {
            let mut out = Vec::new();
            for item in items {
                match item {
                    Value::KeyedArray(ref map) => {
                        if let Some(v) = map.get(&key_str) {
                            out.push(v.clone());
                        } else {
                            out.push(Value::Placeholder);
                        }
                    }
                    _ => out.push(Value::Placeholder),
                }
            }
            Ok(Value::MixedArray(out))
        }
        _ => Err("array:pluck => second argument must be MixedArray".to_string()),
    }
}