mumustring/partial/
repeat.rs1use 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}