gent/interpreter/
string_methods.rs1use crate::errors::{GentError, GentResult};
7use crate::interpreter::Value;
8use crate::Span;
9
10pub fn call_string_method(s: &str, method: &str, args: &[Value]) -> GentResult<Value> {
28 match method {
29 "length" => Ok(Value::Number(s.chars().count() as f64)),
30
31 "trim" => Ok(Value::String(s.trim().to_string())),
32
33 "toLowerCase" => Ok(Value::String(s.to_lowercase())),
34
35 "toUpperCase" => Ok(Value::String(s.to_uppercase())),
36
37 "contains" => {
38 let substr = get_string_arg(args, 0, "contains")?;
39 Ok(Value::Boolean(s.contains(&substr)))
40 }
41
42 "startsWith" => {
43 let prefix = get_string_arg(args, 0, "startsWith")?;
44 Ok(Value::Boolean(s.starts_with(&prefix)))
45 }
46
47 "endsWith" => {
48 let suffix = get_string_arg(args, 0, "endsWith")?;
49 Ok(Value::Boolean(s.ends_with(&suffix)))
50 }
51
52 "split" => {
53 let sep = get_string_arg(args, 0, "split")?;
54 let parts: Vec<Value> = s
55 .split(&sep)
56 .map(|p| Value::String(p.to_string()))
57 .collect();
58 Ok(Value::Array(parts))
59 }
60
61 "replace" => {
62 let old = get_string_arg(args, 0, "replace")?;
63 let new = get_string_arg(args, 1, "replace")?;
64 Ok(Value::String(s.replacen(&old, &new, 1)))
65 }
66
67 _ => Err(GentError::UndefinedProperty {
68 property: method.to_string(),
69 type_name: "String".to_string(),
70 span: Span::default(),
71 }),
72 }
73}
74
75fn get_string_arg(args: &[Value], index: usize, method: &str) -> GentResult<String> {
77 args.get(index)
78 .and_then(|v| match v {
79 Value::String(s) => Some(s.clone()),
80 _ => None,
81 })
82 .ok_or_else(|| {
83 let got = args
84 .get(index)
85 .map(|v| v.type_name())
86 .unwrap_or_else(|| "missing argument".to_string());
87 GentError::TypeError {
88 expected: format!("String argument for {}()", method),
89 got,
90 span: Span::default(),
91 }
92 })
93}