serenity/utils/argument_convert/
member.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 MemberParseError {
11 OutsideGuild,
13 GuildNotInCache,
15 NotFoundOrMalformed,
18}
19
20impl std::error::Error for MemberParseError {}
21
22impl fmt::Display for MemberParseError {
23 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24 match self {
25 Self::OutsideGuild => f.write_str("Tried to find member outside a guild"),
26 Self::GuildNotInCache => f.write_str("Guild is not in cache"),
27 Self::NotFoundOrMalformed => f.write_str("Member not found or unknown format"),
28 }
29 }
30}
31
32#[async_trait::async_trait]
43impl ArgumentConvert for Member {
44 type Err = MemberParseError;
45
46 async fn convert(
47 ctx: impl CacheHttp,
48 guild_id: Option<GuildId>,
49 _channel_id: Option<ChannelId>,
50 s: &str,
51 ) -> Result<Self, Self::Err> {
52 let guild_id = guild_id.ok_or(MemberParseError::OutsideGuild)?;
53
54 if let Some(user_id) = s.parse().ok().or_else(|| crate::utils::parse_user_mention(s)) {
58 if let Ok(member) = guild_id.member(&ctx, user_id).await {
59 return Ok(member);
60 }
61 }
62
63 if let Some((name, discrim)) = crate::utils::parse_user_tag(s) {
67 if let Ok(member_results) = guild_id.search_members(ctx.http(), name, Some(100)).await {
68 if let Some(member) = member_results.into_iter().find(|m| {
69 m.user.name.eq_ignore_ascii_case(name) && m.user.discriminator == discrim
70 }) {
71 return Ok(member);
72 }
73 }
74 }
75
76 if let Ok(member_results) = guild_id.search_members(ctx.http(), s, Some(100)).await {
78 if let Some(member) = member_results.into_iter().find(|m| {
79 m.user.name.eq_ignore_ascii_case(s)
80 || m.nick.as_ref().is_some_and(|nick| nick.eq_ignore_ascii_case(s))
81 }) {
82 return Ok(member);
83 }
84 }
85
86 Err(MemberParseError::NotFoundOrMalformed)
87 }
88}