Skip to main content

tatuin_core/
emoji_transformer.rs

1// SPDX-License-Identifier: MIT
2
3use 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}