ganit_core/eval/functions/text/replace/
mod.rs1use crate::eval::coercion::{to_number, to_string_val};
2use crate::eval::functions::check_arity;
3use crate::types::{ErrorKind, Value};
4
5pub fn replace_fn(args: &[Value]) -> Value {
8 if let Some(err) = check_arity(args, 4, 4) {
9 return err;
10 }
11 let text = match to_string_val(args[0].clone()) {
12 Ok(s) => s,
13 Err(e) => return e,
14 };
15 let start_num = match to_number(args[1].clone()) {
16 Ok(n) => n,
17 Err(e) => return e,
18 };
19 let num_chars = match to_number(args[2].clone()) {
20 Ok(n) => n,
21 Err(e) => return e,
22 };
23 let new_text = match to_string_val(args[3].clone()) {
24 Ok(s) => s,
25 Err(e) => return e,
26 };
27 if start_num < 1.0 || num_chars < 0.0 {
28 return Value::Error(ErrorKind::Value);
29 }
30 let start = (start_num as usize) - 1;
31 let num_chars = num_chars as usize;
32 let chars: Vec<char> = text.chars().collect();
33 let before: String = chars[..start.min(chars.len())].iter().collect();
34 let after_start = (start + num_chars).min(chars.len());
35 let after: String = chars[after_start..].iter().collect();
36 Value::Text(format!("{}{}{}", before, new_text, after))
37}
38
39#[cfg(test)]
40mod tests;