serenity/utils/argument_convert/
user.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 UserParseError {
11 NotFoundOrMalformed,
14}
15
16impl std::error::Error for UserParseError {}
17
18impl fmt::Display for UserParseError {
19 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20 match self {
21 Self::NotFoundOrMalformed => f.write_str("User not found or unknown format"),
22 }
23 }
24}
25
26#[cfg(feature = "cache")]
27fn lookup_by_global_cache(ctx: impl CacheHttp, s: &str) -> Option<User> {
28 let users = &ctx.cache()?.users;
29
30 let lookup_by_id = || users.get(&s.parse().ok()?).map(|u| u.clone());
31
32 let lookup_by_mention = || users.get(&crate::utils::parse_user_mention(s)?).map(|u| u.clone());
33
34 let lookup_by_name_and_discrim = || {
35 let (name, discrim) = crate::utils::parse_user_tag(s)?;
36 users.iter().find_map(|m| {
37 let user = m.value();
38 (user.discriminator == discrim && user.name.eq_ignore_ascii_case(name))
39 .then(|| user.clone())
40 })
41 };
42
43 let lookup_by_name = || {
44 users.iter().find_map(|m| {
45 let user = m.value();
46 (user.name == s).then(|| user.clone())
47 })
48 };
49
50 lookup_by_id()
51 .or_else(lookup_by_mention)
52 .or_else(lookup_by_name_and_discrim)
53 .or_else(lookup_by_name)
54}
55
56#[async_trait::async_trait]
66impl ArgumentConvert for User {
67 type Err = UserParseError;
68
69 async fn convert(
70 ctx: impl CacheHttp,
71 guild_id: Option<GuildId>,
72 channel_id: Option<ChannelId>,
73 s: &str,
74 ) -> Result<Self, Self::Err> {
75 #[cfg(feature = "cache")]
77 if let Some(user) = lookup_by_global_cache(&ctx, s) {
78 return Ok(user);
79 }
80
81 if let Ok(member) = Member::convert(&ctx, guild_id, channel_id, s).await {
83 return Ok(member.user);
84 }
85
86 if let Some(user_id) = s.parse().ok().or_else(|| crate::utils::parse_user_mention(s)) {
88 if let Ok(user) = user_id.to_user(&ctx).await {
91 return Ok(user);
92 }
93 }
94
95 Err(UserParseError::NotFoundOrMalformed)
96 }
97}