revolt_database/models/emojis/
model.rs1use std::collections::HashSet;
2use std::str::FromStr;
3
4use once_cell::sync::Lazy;
5use revolt_models::v0;
6use revolt_result::Result;
7use ulid::Ulid;
8
9use crate::events::client::EventV1;
10use crate::Database;
11
12static PERMISSIBLE_EMOJIS: Lazy<HashSet<String>> = Lazy::new(|| {
13 include_str!("unicode_emoji.txt")
14 .split('\n')
15 .map(|x| x.into())
16 .collect()
17});
18
19auto_derived!(
20 pub struct Emoji {
22 #[serde(rename = "_id")]
24 pub id: String,
25 pub parent: EmojiParent,
27 pub creator_id: String,
29 pub name: String,
31 #[serde(skip_serializing_if = "crate::if_false", default)]
33 pub animated: bool,
34 #[serde(skip_serializing_if = "crate::if_false", default)]
36 pub nsfw: bool,
37 }
38
39 #[serde(tag = "type")]
41 pub enum EmojiParent {
42 Server { id: String },
43 Detached,
44 }
45
46 pub struct PartialEmoji {
48 #[serde(skip_serializing_if = "Option::is_none")]
49 pub name: Option<String>,
50 }
51);
52
53#[allow(clippy::disallowed_methods)]
54impl Emoji {
55 fn parent(&self) -> &str {
57 match &self.parent {
58 EmojiParent::Server { id } => id,
59 EmojiParent::Detached => "",
60 }
61 }
62
63 pub async fn create(&self, db: &Database) -> Result<()> {
65 db.insert_emoji(self).await?;
66
67 EventV1::EmojiCreate(self.clone().into())
68 .p(self.parent().to_string())
69 .await;
70
71 Ok(())
72 }
73
74 pub async fn delete(self, db: &Database) -> Result<()> {
76 EventV1::EmojiDelete {
77 id: self.id.to_string(),
78 }
79 .p(self.parent().to_string())
80 .await;
81
82 db.detach_emoji(&self).await
83 }
84
85 pub async fn update(&mut self, db: &Database, partial: PartialEmoji) -> Result<()> {
87 if let Some(name) = partial.name.clone() {
88 self.name = name;
89 }
90
91 db.update_emoji(&self.id, &partial).await?;
92
93 EventV1::EmojiUpdate {
94 id: self.id.clone(),
95 data: v0::PartialEmoji {
96 name: partial.name.clone(),
97 },
98 }
99 .p(self.parent().to_string())
100 .await;
101
102 Ok(())
103 }
104
105 pub async fn can_use(db: &Database, emoji: &str) -> Result<bool> {
107 if Ulid::from_str(emoji).is_ok() {
108 db.fetch_emoji(emoji).await?;
109 Ok(true)
110 } else {
111 Ok(PERMISSIBLE_EMOJIS.contains(emoji))
112 }
113 }
114}