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_one_arg_partial};

pub fn string_to_string_bridge(_interp: &mut mumu::parser::interpreter::Interpreter, args: Vec<Value>) -> Result<Value, String> {
    match args.len() {
        0 => Ok(make_one_arg_partial(string_to_string_finalize, None)),
        1 => {
            let first = &args[0];
            if is_placeholder(first) {
                Ok(make_one_arg_partial(string_to_string_finalize, None))
            } else {
                string_to_string_finalize(vec![first.clone()])
            }
        }
        n => Err(format!("string:to_string => expected up to 1 argument, got {}", n)),
    }
}

fn string_to_string_finalize(mut args: Vec<Value>) -> Result<Value, String> {
    if args.len() != 1 {
        return Err(format!("string:to_string => finalize => expected 1 real arg, got {}", args.len()));
    }
    let val = args.remove(0);
    let text = match &val {
        Value::Int(i) => i.to_string(),
        Value::Float(ff) => ff.to_string(),
        Value::Long(l) => l.to_string(),
        Value::Bool(b) => b.to_string(),
        Value::SingleString(s) => s.clone(),
        Value::StrArray(ss) => {
            if ss.len() == 1 {
                ss[0].clone()
            } else {
                format!("{:?}", ss)
            }
        }
        Value::IntArray(xs) => format!("{:?}", xs),
        Value::Int2DArray(rows) => format!("{:?}", rows),
        Value::BoolArray(bb) => format!("{:?}", bb),
        Value::KeyedArray(map) => {
            let mut parts = Vec::new();
            for (k, v) in map.iter() {
                parts.push(format!("{}: {:?}", k, v));
            }
            format!("{{ {} }}", parts.join(", "))
        }
        Value::Function(_) => "[Function]".to_string(),
        Value::Placeholder => "_".to_string(),
        Value::FloatArray(ffs) => format!("{:?}", ffs),
        Value::Float2DArray(rows) => format!("{:?}", rows),
        Value::Stream(_) => "[Stream]".to_string(),
        Value::InkIterator(_) => "[InkIterator]".to_string(),
        Value::InkTransform(_) => "[InkTransform]".to_string(),
        Value::Tensor(_) => "[Tensor]".to_string(),
        Value::Regex(_) => "[Regex]".to_string(),
        Value::MixedArray(items) => {
            let strs = items.iter()
                .map(|x| match string_to_string_finalize(vec![x.clone()]) {
                    Ok(Value::SingleString(s)) => s,
                    Ok(other) => format!("{:?}", other),
                    Err(e) => format!("[err:{}]", e),
                })
                .collect::<Vec<_>>()
                .join(", ");
            format!("[{}]", strs)
        }
        Value::Ref(arc_mutex) => {
            let inner = arc_mutex.lock().map_err(|_| "string:to_string => failed to lock Ref".to_string())?;
            let inner_clone = (*inner).clone();
            drop(inner);
            return string_to_string_finalize(vec![inner_clone]);
        }
    };
    Ok(Value::SingleString(text))
}