Skip to main content

mumustring/partial/
replace.rs

1use mumu::parser::types::Value;
2use crate::common::{is_placeholder, make_three_arg_partial};
3
4pub fn string_replace_bridge(_interp: &mut mumu::parser::interpreter::Interpreter, args: Vec<Value>) -> Result<Value, String> {
5    match args.len() {
6        0 => Ok(make_three_arg_partial(string_replace_finalize, None, None, None)),
7        1 => Ok(make_three_arg_partial(string_replace_finalize, Some(args[0].clone()), None, None)),
8        2 => Ok(make_three_arg_partial(string_replace_finalize, Some(args[0].clone()), Some(args[1].clone()), None)),
9        3 => {
10            let s = &args[0];
11            let from = &args[1];
12            let to = &args[2];
13            let s_pl = is_placeholder(s);
14            let from_pl = is_placeholder(from);
15            let to_pl = is_placeholder(to);
16            if !s_pl && !from_pl && !to_pl {
17                string_replace_finalize(vec![s.clone(), from.clone(), to.clone()])
18            } else {
19                Ok(make_three_arg_partial(
20                    string_replace_finalize,
21                    if s_pl { None } else { Some(s.clone()) },
22                    if from_pl { None } else { Some(from.clone()) },
23                    if to_pl { None } else { Some(to.clone()) },
24                ))
25            }
26        }
27        n => Err(format!("string:replace => expected up to 3 arguments, got {}", n)),
28    }
29}
30
31fn string_replace_finalize(mut args: Vec<Value>) -> Result<Value, String> {
32    if args.len() != 3 {
33        return Err(format!(
34            "string:replace => finalize => expected 3 real args, got {}", args.len()));
35    }
36    let s_val = args.remove(0);
37    let from_val = args.remove(0);
38    let to_val = args.remove(0);
39    let s = match s_val {
40        Value::SingleString(s) => s,
41        Value::StrArray(ss) if ss.len() == 1 => ss[0].clone(),
42        other => return Err(format!("string:replace => first arg must be a string, got {:?}", other)),
43    };
44    let from = match from_val {
45        Value::SingleString(s) => s,
46        Value::StrArray(ss) if ss.len() == 1 => ss[0].clone(),
47        other => return Err(format!("string:replace => second arg must be a string, got {:?}", other)),
48    };
49    let to = match to_val {
50        Value::SingleString(s) => s,
51        Value::StrArray(ss) if ss.len() == 1 => ss[0].clone(),
52        other => return Err(format!("string:replace => third arg must be a string, got {:?}", other)),
53    };
54    Ok(Value::SingleString(s.replace(&from, &to)))
55}