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_split_bridge(_interp: &mut mumu::parser::interpreter::Interpreter, args: Vec<Value>) -> Result<Value, String> {
    match args.len() {
        0 => Ok(make_two_arg_partial(string_split_finalize, None, None)),
        1 => Ok(make_two_arg_partial(string_split_finalize, Some(args[0].clone()), None)),
        2 => {
            let sep = &args[0];
            let s = &args[1];
            let sep_is_pl = is_placeholder(sep);
            let s_is_pl = is_placeholder(s);

            if !sep_is_pl && !s_is_pl {
                string_split_finalize(vec![sep.clone(), s.clone()])
            } else {
                Ok(make_two_arg_partial(
                    string_split_finalize,
                    if sep_is_pl { None } else { Some(sep.clone()) },
                    if s_is_pl { None } else { Some(s.clone()) },
                ))
            }
        }
        n => Err(format!("string:split => expected up to 2 arguments, got {}", n)),
    }
}

fn string_split_finalize(mut args: Vec<Value>) -> Result<Value, String> {
    if args.len() != 2 {
        return Err(format!(
            "string:split => finalize => expected 2 real args, got {}",
            args.len()
        ));
    }
    let sep = args.remove(0);
    let data = args.remove(0);
    let s = match data {
        Value::SingleString(s) => s,
        Value::StrArray(ss) if ss.len() == 1 => ss[0].clone(),
        other => return Err(format!("string:split => second arg (string) must be a single string, got {:?}", other)),
    };
    let sep_s = match sep {
        Value::SingleString(s) => s,
        Value::StrArray(ss) if ss.len() == 1 => ss[0].clone(),
        other => return Err(format!("string:split => first arg (sep) must be a single string, got {:?}", other)),
    };
    let parts: Vec<String> = if sep_s.is_empty() {
        s.chars().map(|c| c.to_string()).collect()
    } else {
        s.split(&sep_s).map(|p| p.to_string()).collect()
    };
    Ok(Value::StrArray(parts))
}