mumu-string 0.1.0

String functions and tools plugin for the Lava language
Documentation
use mumu::parser::types::Value;
use crate::common::{is_placeholder, make_two_arg_partial};

pub fn string_concat_bridge(_interp: &mut mumu::parser::interpreter::Interpreter, args: Vec<Value>) -> Result<Value, String> {
    match args.len() {
        0 => Ok(make_two_arg_partial(string_concat_finalize, None, None)),
        1 => {
            let first = &args[0];
            if is_placeholder(first) {
                Ok(make_two_arg_partial(string_concat_finalize, None, None))
            } else {
                Ok(make_two_arg_partial(
                    string_concat_finalize,
                    Some(first.clone()),
                    None,
                ))
            }
        }
        2 => {
            let left = &args[0];
            let right = &args[1];
            let left_is_pl = is_placeholder(left);
            let right_is_pl = is_placeholder(right);

            if !left_is_pl && !right_is_pl {
                string_concat_finalize(vec![left.clone(), right.clone()])
            } else {
                Ok(make_two_arg_partial(
                    string_concat_finalize,
                    if left_is_pl { None } else { Some(left.clone()) },
                    if right_is_pl { None } else { Some(right.clone()) },
                ))
            }
        }
        n => Err(format!("string:concat => expected up to 2 arguments, got {}", n)),
    }
}

fn string_concat_finalize(mut args: Vec<Value>) -> Result<Value, String> {
    if args.len() != 2 {
        return Err(format!(
            "string:concat => finalize => expected 2 real args, got {}",
            args.len()
        ));
    }
    let left_val = args.remove(0);
    let right_val = args.remove(0);

    let left_s = match left_val {
        Value::SingleString(s) => s,
        Value::StrArray(ss) if ss.len() == 1 => ss[0].clone(),
        other => {
            return Err(format!(
                "string:concat => left arg must be a single string, got {:?}",
                other
            ));
        }
    };
    let right_s = match right_val {
        Value::SingleString(s) => s,
        Value::StrArray(ss) if ss.len() == 1 => ss[0].clone(),
        other => {
            return Err(format!(
                "string:concat => right arg must be a single string, got {:?}",
                other
            ));
        }
    };
    Ok(Value::SingleString(left_s + &right_s))
}