twilight_http/request/guild/member/
search_guild_members.rs

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