risingwave_expr_impl/scalar/
translate.rs1use std::collections::HashMap;
16
17use risingwave_expr::function;
18
19#[function("translate(varchar, varchar, varchar) -> varchar")]
20pub fn translate(s: &str, match_str: &str, replace_str: &str, writer: &mut impl std::fmt::Write) {
21 let mut char_map = HashMap::new();
22 let mut match_chars = match_str.chars();
23 let mut replace_chars = replace_str.chars();
24
25 loop {
26 let m = match_chars.next();
27 let r = replace_chars.next();
28 if let Some(match_c) = m {
29 char_map.entry(match_c).or_insert(r);
30 } else {
31 break;
32 }
33 }
34
35 let iter = s.chars().filter_map(|c| match char_map.get(&c) {
36 Some(Some(m)) => Some(*m),
37 Some(None) => None,
38 None => Some(c),
39 });
40 for c in iter {
41 writer.write_char(c).unwrap();
42 }
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48
49 #[test]
50 fn test_translate() {
51 let cases = [
52 ("hello world", "lo", "12", "he112 w2r1d"),
53 (
54 "人之初,性本善。性相近,习相远。",
55 "人性。",
56 "abcd",
57 "a之初,b本善cb相近,习相远c",
58 ),
59 (
60 "奇点无限 RisingWave Labs",
61 "Labs ",
62 "1234",
63 "奇点无限Ri4ingW2ve1234",
64 ),
65 ];
66
67 for (s, match_str, replace_str, expected) in cases {
68 let mut writer = String::new();
69 translate(s, match_str, replace_str, &mut writer);
70 assert_eq!(writer, expected);
71 }
72 }
73}