Skip to main content

twilight_http/request/user/
get_current_user_guilds.rs

1use crate::{
2    client::Client,
3    error::Error,
4    request::{Request, TryIntoRequest},
5    response::{Response, ResponseFuture, marker::ListBody},
6    routing::Route,
7};
8use std::future::IntoFuture;
9use twilight_model::{
10    id::{Id, marker::GuildMarker},
11    user::CurrentUserGuild,
12};
13use twilight_validate::request::{
14    ValidationError, get_current_user_guilds_limit as validate_get_current_user_guilds_limit,
15};
16
17struct GetCurrentUserGuildsFields {
18    after: Option<Id<GuildMarker>>,
19    before: Option<Id<GuildMarker>>,
20    limit: Option<u16>,
21    shard: Option<u64>,
22}
23
24/// Returns a list of guilds for the current user.
25///
26/// # Examples
27///
28/// Get the first 25 guilds with an ID after `300` and before
29/// `400`:
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 after = Id::new(300);
40/// let before = Id::new(400);
41/// let guilds = client
42///     .current_user_guilds()
43///     .after(after)
44///     .before(before)
45///     .limit(25)
46///     .await?;
47/// # Ok(()) }
48/// ```
49#[must_use = "requests must be configured and executed"]
50pub struct GetCurrentUserGuilds<'a> {
51    fields: Result<GetCurrentUserGuildsFields, ValidationError>,
52    http: &'a Client,
53}
54
55impl<'a> GetCurrentUserGuilds<'a> {
56    pub(crate) const fn new(http: &'a Client) -> Self {
57        Self {
58            fields: Ok(GetCurrentUserGuildsFields {
59                after: None,
60                before: None,
61                limit: None,
62                shard: None,
63            }),
64            http,
65        }
66    }
67
68    /// Get guilds after this guild id.
69    pub const fn after(mut self, guild_id: Id<GuildMarker>) -> Self {
70        if let Ok(fields) = self.fields.as_mut() {
71            fields.after = Some(guild_id);
72        }
73
74        self
75    }
76
77    /// Get guilds before this guild id.
78    pub const fn before(mut self, guild_id: Id<GuildMarker>) -> Self {
79        if let Ok(fields) = self.fields.as_mut() {
80            fields.before = Some(guild_id);
81        }
82
83        self
84    }
85
86    /// Set the maximum number of guilds to retrieve.
87    ///
88    /// The minimum is 1 and the maximum is 200. See
89    /// [Discord Docs/Get Current User Guilds].
90    ///
91    /// # Errors
92    ///
93    /// Returns an error of type [`GetCurrentUserGuilds`] if the name length is
94    /// too short or too long.
95    ///
96    /// [`GetCurrentUserGuilds`]: twilight_validate::request::ValidationErrorType::GetCurrentUserGuilds
97    /// [Discord Docs/Get Current User Guilds]: https://discordapp.com/developers/docs/resources/user#get-current-user-guilds-query-string-params
98    pub fn limit(mut self, limit: u16) -> Self {
99        self.fields = self.fields.and_then(|mut fields| {
100            validate_get_current_user_guilds_limit(limit)?;
101            fields.limit = Some(limit);
102
103            Ok(fields)
104        });
105
106        self
107    }
108
109    /// Set the shard to return guilds for. Mandatory for applications using
110    /// Large Bot Sharding.
111    ///
112    /// This is a value of 0 to `max_concurrency` - 1. By default this parameter
113    /// is absent.
114    pub const fn shard(mut self, shard: u64) -> Self {
115        if let Ok(fields) = self.fields.as_mut() {
116            fields.shard = Some(shard);
117        }
118
119        self
120    }
121}
122
123impl IntoFuture for GetCurrentUserGuilds<'_> {
124    type Output = Result<Response<ListBody<CurrentUserGuild>>, Error>;
125
126    type IntoFuture = ResponseFuture<ListBody<CurrentUserGuild>>;
127
128    fn into_future(self) -> Self::IntoFuture {
129        let http = self.http;
130
131        match self.try_into_request() {
132            Ok(request) => http.request(request),
133            Err(source) => ResponseFuture::error(source),
134        }
135    }
136}
137
138impl TryIntoRequest for GetCurrentUserGuilds<'_> {
139    fn try_into_request(self) -> Result<Request, Error> {
140        let fields = self.fields.map_err(Error::validation)?;
141
142        Ok(Request::from_route(&Route::GetGuilds {
143            after: fields.after.map(Id::get),
144            before: fields.before.map(Id::get),
145            limit: fields.limit,
146            shard: fields.shard,
147        }))
148    }
149}