Skip to main content

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