revolt_database/models/emojis/
model.rs

1use std::collections::HashSet;
2use std::str::FromStr;
3
4use once_cell::sync::Lazy;
5use revolt_result::Result;
6use ulid::Ulid;
7
8use crate::events::client::EventV1;
9use crate::Database;
10
11static PERMISSIBLE_EMOJIS: Lazy<HashSet<String>> = Lazy::new(|| {
12    include_str!("unicode_emoji.txt")
13        .split('\n')
14        .map(|x| x.into())
15        .collect()
16});
17
18auto_derived!(
19    /// Emoji
20    pub struct Emoji {
21        /// Unique Id
22        #[serde(rename = "_id")]
23        pub id: String,
24        /// What owns this emoji
25        pub parent: EmojiParent,
26        /// Uploader user id
27        pub creator_id: String,
28        /// Emoji name
29        pub name: String,
30        /// Whether the emoji is animated
31        #[serde(skip_serializing_if = "crate::if_false", default)]
32        pub animated: bool,
33        /// Whether the emoji is marked as nsfw
34        #[serde(skip_serializing_if = "crate::if_false", default)]
35        pub nsfw: bool,
36    }
37
38    /// Parent Id of the emoji
39    #[serde(tag = "type")]
40    pub enum EmojiParent {
41        Server { id: String },
42        Detached,
43    }
44);
45
46#[allow(clippy::disallowed_methods)]
47impl Emoji {
48    /// Get parent id
49    fn parent(&self) -> &str {
50        match &self.parent {
51            EmojiParent::Server { id } => id,
52            EmojiParent::Detached => "",
53        }
54    }
55
56    /// Create an emoji
57    pub async fn create(&self, db: &Database) -> Result<()> {
58        db.insert_emoji(self).await?;
59
60        EventV1::EmojiCreate(self.clone().into())
61            .p(self.parent().to_string())
62            .await;
63
64        Ok(())
65    }
66
67    /// Delete an emoji
68    pub async fn delete(self, db: &Database) -> Result<()> {
69        EventV1::EmojiDelete {
70            id: self.id.to_string(),
71        }
72        .p(self.parent().to_string())
73        .await;
74
75        db.detach_emoji(&self).await
76    }
77
78    /// Check whether we can use a given emoji
79    pub async fn can_use(db: &Database, emoji: &str) -> Result<bool> {
80        if Ulid::from_str(emoji).is_ok() {
81            db.fetch_emoji(emoji).await?;
82            Ok(true)
83        } else {
84            Ok(PERMISSIBLE_EMOJIS.contains(emoji))
85        }
86    }
87}