Skip to main content

teaql_tool_std/
emoji.rs

1pub struct EmojiTool;
2
3impl EmojiTool {
4    pub fn new() -> Self {
5        Self
6    }
7
8    /// Check if a string contains any emoji characters
9    pub fn contains_emoji(&self, text: impl AsRef<str>) -> bool {
10        let text = text.as_ref();
11        text.chars().any(|c| self.is_emoji_char(c))
12    }
13
14    /// Remove all emoji characters from a string
15    pub fn remove_all(&self, text: impl AsRef<str>) -> String {
16        let text = text.as_ref();
17        text.chars().filter(|c| !self.is_emoji_char(*c)).collect()
18    }
19
20    /// Replace all emoji characters in a string with a replacement string
21    pub fn replace_all(&self, text: impl AsRef<str>, replacement: impl AsRef<str>) -> String {
22        let text = text.as_ref();
23        let rep = replacement.as_ref();
24        let mut result = String::with_capacity(text.len());
25        for c in text.chars() {
26            if self.is_emoji_char(c) {
27                result.push_str(rep);
28            } else {
29                result.push(c);
30            }
31        }
32        result
33    }
34
35    /// Internal logic to detect common Emoji Unicode blocks
36    fn is_emoji_char(&self, c: char) -> bool {
37        let u = c as u32;
38        // Common emoji blocks
39        (0x1F300..=0x1F5FF).contains(&u) || // Miscellaneous Symbols and Pictographs
40        (0x1F900..=0x1F9FF).contains(&u) || // Supplemental Symbols and Pictographs
41        (0x1F600..=0x1F64F).contains(&u) || // Emoticons
42        (0x1F680..=0x1F6FF).contains(&u) || // Transport and Map
43        (0x2600..=0x26FF).contains(&u)   || // Miscellaneous Symbols
44        (0x2700..=0x27BF).contains(&u)   || // Dingbats
45        (0xFE00..=0xFE0F).contains(&u)   || // Variation Selectors
46        (0x1F1E6..=0x1F1FF).contains(&u) || // Regional indicator symbol
47        (0x1F018..=0x1F270).contains(&u) || // Various enclosed alphanumerics
48        (0x1F700..=0x1F77F).contains(&u) || // Alchemical Symbols
49        (0x1F780..=0x1F7FF).contains(&u) || // Geometric Shapes Extended
50        (0x1F800..=0x1F8FF).contains(&u) || // Supplemental Arrows-C
51        (0x1FA70..=0x1FAFF).contains(&u)    // Symbols and Pictographs Extended-A
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58
59    #[test]
60    fn test_emoji_tool() {
61        let tool = EmojiTool::new();
62        assert!(tool.contains_emoji("Hello 😀!"));
63        assert!(!tool.contains_emoji("Hello World!"));
64        
65        let cleaned = tool.remove_all("Bad 💩 Data 🤡!");
66        assert_eq!(cleaned, "Bad  Data !");
67    }
68}