serenity/utils/argument_convert/
emoji.rs1use std::fmt;
2
3use super::ArgumentConvert;
4use crate::model::prelude::*;
5use crate::prelude::*;
6
7#[non_exhaustive]
9#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
10pub enum EmojiParseError {
11 OutsideGuild,
13 FailedToRetrieveGuild,
15 NotFoundOrMalformed,
18}
19
20impl std::error::Error for EmojiParseError {}
21
22impl fmt::Display for EmojiParseError {
23 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24 match self {
25 Self::OutsideGuild => f.write_str("Tried to find emoji outside a guild"),
26 Self::FailedToRetrieveGuild => f.write_str("Could not retrieve guild data"),
27 Self::NotFoundOrMalformed => f.write_str("Emoji not found or unknown format"),
28 }
29 }
30}
31
32#[async_trait::async_trait]
41impl ArgumentConvert for Emoji {
42 type Err = EmojiParseError;
43
44 async fn convert(
45 ctx: impl CacheHttp,
46 guild_id: Option<GuildId>,
47 _channel_id: Option<ChannelId>,
48 s: &str,
49 ) -> Result<Self, Self::Err> {
50 let guild_id = guild_id.ok_or(EmojiParseError::OutsideGuild)?;
52 let guild = guild_id
53 .to_partial_guild(&ctx)
54 .await
55 .map_err(|_| EmojiParseError::FailedToRetrieveGuild)?;
56
57 let direct_id = s.parse().ok();
58 let id_from_mention = crate::utils::parse_emoji(s).map(|e| e.id);
59
60 if let Some(emoji_id) = direct_id.or(id_from_mention) {
61 if let Some(emoji) = guild.emojis.get(&emoji_id).cloned() {
62 return Ok(emoji);
63 }
64 }
65
66 if let Some(emoji) =
67 guild.emojis.values().find(|emoji| emoji.name.eq_ignore_ascii_case(s)).cloned()
68 {
69 return Ok(emoji);
70 }
71
72 Err(EmojiParseError::NotFoundOrMalformed)
73 }
74}