Skip to main content

twilight_http/request/guild/member/
get_guild_members.rs

1#[cfg(not(target_os = "wasi"))]
2use crate::response::{Response, ResponseFuture, marker::ListBody};
3use crate::{
4    client::Client,
5    error::Error,
6    request::{Request, TryIntoRequest},
7    routing::Route,
8};
9use std::future::IntoFuture;
10use twilight_model::{
11    guild::Member,
12    id::{
13        Id,
14        marker::{GuildMarker, UserMarker},
15    },
16};
17use twilight_validate::request::{
18    ValidationError, get_guild_members_limit as validate_get_guild_members_limit,
19};
20
21struct GetGuildMembersFields {
22    after: Option<Id<UserMarker>>,
23    limit: Option<u16>,
24}
25
26/// Get the members of a guild, by id.
27///
28/// The upper limit to this request is 1000. If more than 1000 members are needed, the requests
29/// must be chained. Discord defaults the limit to 1.
30///
31/// # Examples
32///
33/// Get the first 500 members of guild `100` after user ID `3000`:
34///
35/// ```no_run
36/// use twilight_http::Client;
37/// use twilight_model::id::Id;
38///
39/// # #[tokio::main]
40/// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
41/// let client = Client::new("my token".to_owned());
42///
43/// let guild_id = Id::new(100);
44/// let user_id = Id::new(3000);
45/// let members = client
46///     .guild_members(guild_id)
47///     .after(user_id)
48///     .limit(500)
49///     .await?;
50/// # Ok(()) }
51/// ```
52#[must_use = "requests must be configured and executed"]
53pub struct GetGuildMembers<'a> {
54    fields: Result<GetGuildMembersFields, ValidationError>,
55    guild_id: Id<GuildMarker>,
56    http: &'a Client,
57}
58
59impl<'a> GetGuildMembers<'a> {
60    pub(crate) const fn new(http: &'a Client, guild_id: Id<GuildMarker>) -> Self {
61        Self {
62            fields: Ok(GetGuildMembersFields {
63                after: None,
64                limit: None,
65            }),
66            guild_id,
67            http,
68        }
69    }
70
71    /// Sets the user ID to get members after.
72    pub const fn after(mut self, after: Id<UserMarker>) -> Self {
73        if let Ok(fields) = self.fields.as_mut() {
74            fields.after = Some(after);
75        }
76
77        self
78    }
79
80    /// Sets the number of members to retrieve per request.
81    ///
82    /// The limit must be greater than 0 and less than 1000.
83    ///
84    /// # Errors
85    ///
86    /// Returns an error of type [`GetGuildMembers`] if the limit is 0 or
87    /// greater than 1000.
88    ///
89    /// [`GetGuildMembers`]: twilight_validate::request::ValidationErrorType::GetGuildMembers
90    pub fn limit(mut self, limit: u16) -> Self {
91        self.fields = self.fields.and_then(|mut fields| {
92            validate_get_guild_members_limit(limit)?;
93            fields.limit = Some(limit);
94
95            Ok(fields)
96        });
97
98        self
99    }
100}
101
102#[cfg(not(target_os = "wasi"))]
103impl IntoFuture for GetGuildMembers<'_> {
104    type Output = Result<Response<ListBody<Member>>, Error>;
105
106    type IntoFuture = ResponseFuture<ListBody<Member>>;
107
108    fn into_future(self) -> Self::IntoFuture {
109        let http = self.http;
110
111        match self.try_into_request() {
112            Ok(request) => http.request(request),
113            Err(source) => ResponseFuture::error(source),
114        }
115    }
116}
117
118impl TryIntoRequest for GetGuildMembers<'_> {
119    fn try_into_request(self) -> Result<Request, Error> {
120        let fields = self.fields.map_err(Error::validation)?;
121
122        Ok(Request::from_route(&Route::GetGuildMembers {
123            after: fields.after.map(Id::get),
124            guild_id: self.guild_id.get(),
125            limit: fields.limit,
126        }))
127    }
128}