Skip to main content

mumustring/partial/
repeat.rs

1use mumu::parser::types::Value;
2use crate::common::{is_placeholder, make_two_arg_partial};
3
4pub fn string_repeat_bridge(_interp: &mut mumu::parser::interpreter::Interpreter, args: Vec<Value>) -> Result<Value, String> {
5    match args.len() {
6        0 => Ok(make_two_arg_partial(string_repeat_finalize, None, None)),
7        1 => Ok(make_two_arg_partial(string_repeat_finalize, Some(args[0].clone()), None)),
8        2 => {
9            let s = &args[0];
10            let n = &args[1];
11            let s_pl = is_placeholder(s);
12            let n_pl = is_placeholder(n);
13            if !s_pl && !n_pl {
14                string_repeat_finalize(vec![s.clone(), n.clone()])
15            } else {
16                Ok(make_two_arg_partial(
17                    string_repeat_finalize,
18                    if s_pl { None } else { Some(s.clone()) },
19                    if n_pl { None } else { Some(n.clone()) },
20                ))
21            }
22        }
23        n => Err(format!("string:repeat => expected up to 2 arguments, got {}", n)),
24    }
25}
26
27fn string_repeat_finalize(mut args: Vec<Value>) -> Result<Value, String> {
28    if args.len() != 2 {
29        return Err(format!("string:repeat => finalize => expected 2 real args, got {}", args.len()));
30    }
31    let s_val = args.remove(0);
32    let n_val = args.remove(0);
33    let s = match s_val {
34        Value::SingleString(s) => s,
35        Value::StrArray(ss) if ss.len() == 1 => ss[0].clone(),
36        other => return Err(format!("string:repeat => first arg must be string, got {:?}", other)),
37    };
38    let n = match n_val {
39        Value::Int(i) => i,
40        other => return Err(format!("string:repeat => second arg must be int, got {:?}", other)),
41    };
42    if n < 0 || n > 8192 {
43        return Err("string:repeat => repeat count must be in 0..8192".to_string());
44    }
45    Ok(Value::SingleString(s.repeat(n as usize)))
46}