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