risingwave_expr_impl/scalar/
replace.rs1use std::fmt::Write;
16
17use risingwave_expr::function;
18
19#[function("replace(varchar, varchar, varchar) -> varchar")]
20pub fn replace(s: &str, from_str: &str, to_str: &str, writer: &mut impl Write) {
21    if from_str.is_empty() {
22        writer.write_str(s).unwrap();
23        return;
24    }
25    let mut last = 0;
26    while let Some(mut start) = s[last..].find(from_str) {
27        start += last;
28        writer.write_str(&s[last..start]).unwrap();
29        writer.write_str(to_str).unwrap();
30        last = start + from_str.len();
31    }
32    writer.write_str(&s[last..]).unwrap();
33}
34
35#[cfg(test)]
36mod tests {
37    use super::*;
38
39    #[test]
40    fn test_replace() {
41        let cases = vec![
42            ("hello, word", "我的", "world", "hello, word"),
43            ("hello, word", "", "world", "hello, word"),
44            ("hello, word", "word", "world", "hello, world"),
45            ("hello, world", "world", "", "hello, "),
46            ("你是❤️,是暖,是希望", "是", "非", "你非❤️,非暖,非希望"),
47            ("👴笑了", "👴", "爷爷", "爷爷笑了"),
48        ];
49
50        for (s, from_str, to_str, expected) in cases {
51            let mut writer = String::new();
52            replace(s, from_str, to_str, &mut writer);
53            assert_eq!(writer, expected);
54        }
55    }
56}