tatuin_core/
emoji_transformer.rs1use std::sync::LazyLock;
4
5use regex::Regex;
6
7use crate::RichStringTransformerTrait;
8
9static RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"(:([\w+-]+):)").unwrap());
10
11#[derive(Debug)]
12pub struct EmojiTransformer {}
13
14impl RichStringTransformerTrait for EmojiTransformer {
15 fn transform(&self, s: &str) -> String {
16 let mut result = String::new();
17 let mut last_end: usize = 0;
18
19 for cap in RE.captures_iter(s) {
20 let (full, [_, emoji_shortcode]) = cap.extract();
21 let m = cap.get_match();
22
23 result.push_str(&s[last_end..m.start()]);
24 if let Some(emoji) = emojis::get_by_shortcode(emoji_shortcode) {
25 result.push_str(emoji.as_str());
26 } else {
27 result.push_str(full);
28 }
29
30 last_end = m.end();
31 }
32
33 result.push_str(&s[last_end..]);
34 result
35 }
36}
37
38#[cfg(test)]
39mod test {
40 use crate::{EmojiTransformer, RichStringTransformerTrait};
41
42 #[test]
43 fn single_emoji() {
44 assert_eq!("😄", EmojiTransformer {}.transform(":smile:"));
45 }
46
47 #[test]
48 fn inside_string() {
49 assert_eq!(
50 "Some text 😄 some text",
51 EmojiTransformer {}.transform("Some text :smile: some text")
52 );
53 }
54
55 #[test]
56 fn unknown_emoji() {
57 assert_eq!(
58 "Some text :abrakadabra: some text",
59 EmojiTransformer {}.transform("Some text :abrakadabra: some text")
60 );
61 }
62}