1use regex::{Captures, Regex};
2use std::borrow::Cow;
3
4#[cfg(feature = "emojidb")]
5mod data_generated_expanded;
6#[cfg(feature = "emojidb")]
7use crate::data_generated_expanded::EMOJI;
8
9#[cfg(not(feature = "emojidb"))]
10mod data_generated_genmoji;
11#[cfg(not(feature = "emojidb"))]
12use crate::data_generated_genmoji::EMOJI;
13
14pub fn get(name: &str) -> Option<&str> {
20 EMOJI.get(name).map(|s| *s)
21}
22
23pub fn all() -> impl Iterator<Item = (&'static str, &'static str)> {
27 EMOJI.entries.iter().map(|&x| x)
28}
29
30pub struct Replacer {
37 regex: Regex,
38}
39
40impl Replacer {
41 pub fn new() -> Self {
43 Self {
44 regex: Regex::new(r":([a-z1238+-][a-z0-9_-]*):").unwrap(),
45 }
46 }
47
48 pub fn replace_all<'a>(&self, text: &'a str) -> Cow<'a, str> {
54 self.regex.replace_all(text, EmojiRegexReplacer)
55 }
56}
57
58struct EmojiRegexReplacer;
59impl regex::Replacer for EmojiRegexReplacer {
60 fn replace_append(&mut self, capts: &Captures<'_>, dst: &mut String) {
61 dst.push_str(EMOJI.get(&capts[1]).copied().unwrap_or_else(|| &capts[0]));
62 }
63}
64
65#[test]
66fn replacer() {
67 let r = Replacer::new();
68 assert_eq!(
69 "hello 😄 :not_emoji_404:",
70 r.replace_all("hello :smile: :not_emoji_404:")
71 );
72 assert_eq!(
73 Replacer::new().replace_all(":cat: make me :smile:"),
74 "\u{01F431} make me \u{01F604}"
75 );
76}
77
78#[test]
79fn get_existing() {
80 assert_eq!(get("smile"), Some("\u{01F604}"));
81 assert_eq!(get("poop"), Some("\u{01F4A9}"));
82 assert_eq!(get("cat"), Some("\u{01F431}"));
83 assert_eq!(get("+1"), Some("👍"));
84 assert_eq!(get("-1"), Some("\u{01F44E}"));
85 assert_eq!(get("8ball"), Some("\u{01F3B1}"));
86}
87
88#[test]
89fn get_nonexistent() {
90 assert_eq!(get("stuff"), None);
91 assert_eq!(get("++"), None);
92 assert_eq!(get("--"), None);
93 assert_eq!(get("666"), None);
94}
95
96#[cfg(not(feature = "emojidb"))]
97mod genmoji_only_tests {
98 #[test]
99 fn get_nonexistent() {
100 assert_eq!(super::get("robot_face"), None);
101 }
102}
103
104#[cfg(feature = "emojidb")]
105mod emojidb_only_tests {
106 #[test]
107 fn get_emojidb_only_codes() {
108 assert_eq!(super::get("robot_face"), Some("🤖"));
109 }
110}